|
|
@@ -1,6 +1,8 @@
|
|
|
package rfc3961
|
|
|
|
|
|
import (
|
|
|
+ "bytes"
|
|
|
+
|
|
|
"gopkg.in/jcmturner/gokrb5.v6/crypto/etype"
|
|
|
)
|
|
|
|
|
|
@@ -63,10 +65,10 @@ func RandomToKey(b []byte) []byte {
|
|
|
|
|
|
// DES3RandomToKey returns a key from the bytes provided according to the definition in RFC 3961 for DES3 etypes.
|
|
|
func DES3RandomToKey(b []byte) []byte {
|
|
|
- r := stretch56Bits(b[:7])
|
|
|
- r2 := stretch56Bits(b[7:14])
|
|
|
+ r := fixWeakKey(stretch56Bits(b[:7]))
|
|
|
+ r2 := fixWeakKey(stretch56Bits(b[7:14]))
|
|
|
r = append(r, r2...)
|
|
|
- r3 := stretch56Bits(b[14:21])
|
|
|
+ r3 := fixWeakKey(stretch56Bits(b[14:21]))
|
|
|
r = append(r, r3...)
|
|
|
return r
|
|
|
}
|
|
|
@@ -132,3 +134,45 @@ func calcEvenParity(b byte) (uint8, uint8) {
|
|
|
}
|
|
|
return lowestbit, b
|
|
|
}
|
|
|
+
|
|
|
+func fixWeakKey(b []byte) []byte {
|
|
|
+ if weak(b) {
|
|
|
+ b[7] ^= 0xF0
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+func weak(b []byte) bool {
|
|
|
+ // weak keys from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-67r1.pdf
|
|
|
+ weakKeys := [4][]byte{
|
|
|
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
|
|
|
+ {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
|
|
|
+ {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1},
|
|
|
+ {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
|
|
|
+ }
|
|
|
+ semiWeakKeys := [12][]byte{
|
|
|
+ {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E},
|
|
|
+ {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01},
|
|
|
+ {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1},
|
|
|
+ {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01},
|
|
|
+ {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE},
|
|
|
+ {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01},
|
|
|
+ {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1},
|
|
|
+ {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E},
|
|
|
+ {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE},
|
|
|
+ {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E},
|
|
|
+ {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
|
|
|
+ {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1},
|
|
|
+ }
|
|
|
+ for _, k := range weakKeys {
|
|
|
+ if bytes.Equal(b, k) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for _, k := range semiWeakKeys {
|
|
|
+ if bytes.Equal(b, k) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|