diff --git a/compiler/tests/crypto/gcm/aes128_gcm.mpcl b/compiler/tests/crypto/gcm/aes128_gcm.mpcl new file mode 100644 index 00000000..92bcc7ec --- /dev/null +++ b/compiler/tests/crypto/gcm/aes128_gcm.mpcl @@ -0,0 +1,25 @@ +// -*- go -*- + +package main + +import ( + "crypto/cipher/gcm" +) + +type Garbler struct { + key []byte + iv []byte + plain []byte +} + +// @Hex +// @LSB +// @Test 0x00000000000000000000000000000000,0x000000000000000000000000,_ _ = _ 0x58e2fccefa7e3061367f1d57a4e7455a +// @Test 0x00000000000000000000000000000000,0x000000000000000000000000,0x00000000000000000000000000000000 _ = 0x0388dace60b6a392f328c2b971b2fe78 0xab6e47d42cec13bdf53a67b21257bddf +// @Test 0xfeffe9928665731c6d6a8f9467308308,0xcafebabefacedbaddecaf888,0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 _ = 0x42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985 0x4d5c2af327cd64a62cf35abd2ba6fab4 +// @Test 0xfeffe9928665731c6d6a8f9467308308,0xcafebabefacedbaddecaf888,0xd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 0xfeedfacedeadbeeffeedfacedeadbeefabaddad2 = 0x42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091 0x5bc94fbc3221a5db94fae95ae7121a47 +func main(g Garbler, aad []byte) ([]byte, []byte) { + cipher := gcm.EncryptAES128(g.key, g.iv, g.plain, aad) + split := len(g.plain) + return cipher[:split], cipher[split:] +} diff --git a/pkg/crypto/cipher/gcm/gcm.mpcl b/pkg/crypto/cipher/gcm/gcm.mpcl index 4fecfbcf..a764ac77 100644 --- a/pkg/crypto/cipher/gcm/gcm.mpcl +++ b/pkg/crypto/cipher/gcm/gcm.mpcl @@ -43,7 +43,19 @@ func EncryptAES128(key [16]byte, nonce [NonceSize]byte, // Auth data. var x uint128 = 0 - // XXX additionalData + + // Add additionalData to auth data. + for i := 0; i < len(additionalData); i += aes.BlockSize { + for j := 0; j < aes.BlockSize; j++ { + if i+j < len(additionalData) { + block[j] = additionalData[i+j] + } else { + block[j] = 0 + } + } + x ^= byteToUint128(block) + x = multGF2Pow128(x, h) + } var cipher [len(plaintext) + 16]byte var cipherBlock [aes.BlockSize]byte @@ -51,19 +63,22 @@ func EncryptAES128(key [16]byte, nonce [NonceSize]byte, for i := 0; i < len(plaintext); i += aes.BlockSize { counter = incr(counter) block = aes.Block128(key, counter) - for j := 0; i+j < len(plaintext) && j < aes.BlockSize; j++ { - cipher[i+j] = plaintext[i+j] ^ block[j] - cipherBlock[j] = cipher[i+j] + for j := 0; j < aes.BlockSize; j++ { + if i+j < len(plaintext) { + cipher[i+j] = plaintext[i+j] ^ block[j] + cipherBlock[j] = cipher[i+j] + } else { + cipherBlock[j] = 0 + } } - // Auth data. x ^= byteToUint128(cipherBlock) x = multGF2Pow128(x, h) } // len(A) || len(C) - var l uint128 = 0 - l |= uint128(0) << 64 + var l uint128 + l |= uint128(len(additionalData)*8) << 64 l |= uint128(len(plaintext) * 8) x ^= l @@ -101,11 +116,22 @@ func DecryptAES128(key [16]byte, nonce [NonceSize]byte, // Auth data. var x uint128 = 0 - // XXX additionalData + + // Add additionalData to auth data. + for i := 0; i < len(additionalData); i += aes.BlockSize { + for j := 0; j < aes.BlockSize; j++ { + if i+j < len(additionalData) { + block[j] = additionalData[i+j] + } else { + block[j] = 0 + } + } + x ^= byteToUint128(block) + x = multGF2Pow128(x, h) + } if len(ciphertext) < TagSize { - // XXX should return []byte - return ciphertext, false + return ciphertext[:0], false } cipherLen := len(ciphertext) - TagSize cipher := ciphertext[0:cipherLen] @@ -117,9 +143,13 @@ func DecryptAES128(key [16]byte, nonce [NonceSize]byte, for i := 0; i < len(cipher); i += aes.BlockSize { counter = incr(counter) block = aes.Block128(key, counter) - for j := 0; i+j < len(cipher) && j < aes.BlockSize; j++ { - cipherBlock[j] = cipher[i+j] - plain[i+j] = cipher[i+j] ^ block[j] + for j := 0; j < aes.BlockSize; j++ { + if i+j < len(cipher) { + cipherBlock[j] = cipher[i+j] + plain[i+j] = cipher[i+j] ^ block[j] + } else { + cipherBlock[j] = 0 + } } // Auth data. @@ -129,7 +159,7 @@ func DecryptAES128(key [16]byte, nonce [NonceSize]byte, // len(A) || len(C) var l uint128 = 0 - l |= uint128(0) << 64 + l |= uint128(len(additionalData)*8) << 64 l |= uint128(len(plain) * 8) x ^= l