summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2017-09-18 02:44:22 +0200
committerChristian Pointner <equinox@anytun.org>2017-09-18 02:44:22 +0200
commit711aff22f09c52cfb16e82889800e84ea716a231 (patch)
treee0112ba27e92de739ca33c9be4711ed5ea9cd7cc
parentimplemented AES-CTR key derivation (needs testing) (diff)
some more testcases and fixes
-rw-r--r--satp/crypto-kd-aesctr.go10
-rw-r--r--satp/crypto-kd-aesctr_test.go74
2 files changed, 81 insertions, 3 deletions
diff --git a/satp/crypto-kd-aesctr.go b/satp/crypto-kd-aesctr.go
index 7b8c97a..58a1c04 100644
--- a/satp/crypto-kd-aesctr.go
+++ b/satp/crypto-kd-aesctr.go
@@ -56,8 +56,12 @@ func (kd *AESCTRKeyDerivation) generateCTR(dir KeyDirection, usage KeyUsage, seq
keyID := [8]byte{}
binary.BigEndian.PutUint32(keyID[:4], getKDLabel(dir, usage))
binary.BigEndian.PutUint32(keyID[4:], sequenceNumber)
- for i, b := range keyID { // unfortunately crypto.xorBytes is not exported...
- ctr[len(kd.salt)-i] ^= b
+
+ // unfortunately crypto.xorBytes is not exported...
+ offset := len(kd.salt) - len(keyID)
+ n := len(keyID)
+ for i := 0; i < n; i++ {
+ ctr[offset+i] = ctr[offset+i] ^ keyID[i]
}
}
@@ -66,7 +70,7 @@ func (kd *AESCTRKeyDerivation) Generate(dir KeyDirection, usage KeyUsage, sequen
// from this function and whence will get allocated on the stack
ctr := [aes.BlockSize]byte{}
kd.generateCTR(dir, usage, sequenceNumber, ctr[:])
- for i, _ := range out { // unfortunately there is no memset-style function in go...
+ for i := range out { // unfortunately there is no memset-style function in go...
out[i] = 0
}
c := cipher.NewCTR(kd.cipher, ctr[:])
diff --git a/satp/crypto-kd-aesctr_test.go b/satp/crypto-kd-aesctr_test.go
index 0426f3e..d625a16 100644
--- a/satp/crypto-kd-aesctr_test.go
+++ b/satp/crypto-kd-aesctr_test.go
@@ -31,6 +31,8 @@
package satp
import (
+ "bytes"
+ "crypto/aes"
"math/rand"
"testing"
)
@@ -65,3 +67,75 @@ func TestAESCTRKeyDerivationNew(t *testing.T) {
}
}
}
+
+func TestAESCTRKeyDerivationGenerateCtr(t *testing.T) {
+ testvectors := []struct {
+ salt []byte
+ dir KeyDirection
+ usage KeyUsage
+ sequenceNumber uint32
+ ctr []byte
+ }{
+ {[]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, DirLeft, UsageEncryptKey, 0x12345678,
+ []byte{0, 0, 0, 0, 0, 0, 0x35, 0x6A, 0x19, 0x2B, 0x12, 0x34, 0x56, 0x78, 0, 0}},
+ {[]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, DirRight, UsageEncryptSalt, 0x01020304,
+ []byte{0, 0, 0, 0, 0, 0, 0x1B, 0x64, 0x53, 0x89, 0x01, 0x02, 0x03, 0x04, 0, 0}},
+ {[]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, DirLeft, UsageAuthKey, 0xdeadbeef,
+ []byte{0, 0, 0, 0, 0, 0, 0xAC, 0x34, 0x78, 0xD6, 0xDE, 0xAD, 0xBE, 0xEF, 0, 0}},
+ {[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, DirLeft, UsageAuthKey, 0xdeadbeef,
+ []byte{0, 1, 2, 3, 4, 5, 0xAA, 0x33, 0x70, 0xDF, 0xD4, 0xA6, 0xB2, 0xE2, 0, 0}},
+ {[]byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}, DirLeft, UsageEncryptSalt, 0x01020304,
+ []byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xA9, 0x2E, 0x7A, 0xEE, 0x57, 0x7A, 0x99, 0xB8, 0, 0}},
+ }
+
+ for _, vector := range testvectors {
+ key := [aes.BlockSize]byte{}
+ kd, err := NewAESCTRKeyDerivation(key[:], vector.salt)
+ if err != nil {
+ t.Fatal("unexpected error:", err)
+ }
+ aesCTR := kd.(*AESCTRKeyDerivation)
+
+ ctr := [aes.BlockSize]byte{}
+ aesCTR.generateCTR(vector.dir, vector.usage, vector.sequenceNumber, ctr[:])
+ if bytes.Compare(ctr[:], vector.ctr) != 0 {
+ t.Fatalf("resulting ctr is invalid, is: '%v', should be '%v'", ctr[:], vector.ctr)
+ }
+ }
+}
+
+func TestAESCTRKeyDerivationGenerateRepeat(t *testing.T) {
+ var buffer [256]byte
+ rand.Read(buffer[:])
+
+ testvectors := []struct {
+ key []byte
+ salt []byte
+ dir KeyDirection
+ usage KeyUsage
+ sequenceNumber uint32
+ length int
+ }{
+ {buffer[:16], buffer[16:30], DirLeft, UsageEncryptKey, 0x12345678, 23},
+ {buffer[32:48], buffer[48:62], DirLeft, UsageEncryptKey, 0x1, 16},
+ {buffer[64:80], buffer[80:94], DirLeft, UsageEncryptKey, 0x1, 20},
+ {buffer[96:112], buffer[112:126], DirLeft, UsageEncryptKey, 0x1, 14},
+ }
+
+ for _, vector := range testvectors {
+ key := [aes.BlockSize]byte{}
+ kd, err := NewAESCTRKeyDerivation(key[:], vector.salt)
+ if err != nil {
+ t.Fatal("unexpected error:", err)
+ }
+
+ out1 := make([]byte, vector.length)
+ out2 := buffer[128 : 128+vector.length]
+ kd.Generate(vector.dir, vector.usage, vector.sequenceNumber, out1)
+ kd.Generate(vector.dir, vector.usage, vector.sequenceNumber, out2)
+
+ if bytes.Compare(out1, out2) != 0 {
+ t.Fatalf("result of 2 consecutive key generations differ, out1: '%v', out2: '%v'", out1, out2)
+ }
+ }
+}