github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/composite/register_ecdh_aead_enc_helper_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package composite 8 9 import ( 10 "encoding/hex" 11 "encoding/json" 12 "fmt" 13 "testing" 14 15 "github.com/golang/protobuf/proto" 16 "github.com/google/tink/go/aead" 17 subtleaead "github.com/google/tink/go/aead/subtle" 18 "github.com/google/tink/go/mac" 19 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 20 "github.com/google/tink/go/signature" 21 "github.com/google/tink/go/subtle/random" 22 "github.com/stretchr/testify/require" 23 "golang.org/x/crypto/chacha20poly1305" 24 "golang.org/x/crypto/poly1305" 25 26 cbchmacaead "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/aead" 27 subtlecbchmacaead "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/aead/subtle" 28 aeadpb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/aes_cbc_hmac_aead_go_proto" 29 ) 30 31 func newKeyTemplates() ([]*tinkpb.KeyTemplate, []int) { 32 twoKeys := 2 33 34 return []*tinkpb.KeyTemplate{ 35 aead.ChaCha20Poly1305KeyTemplate(), 36 aead.XChaCha20Poly1305KeyTemplate(), 37 aead.AES256GCMKeyTemplate(), 38 aead.AES128GCMKeyTemplate(), 39 cbchmacaead.AES128CBCHMACSHA256KeyTemplate(), 40 cbchmacaead.AES192CBCHMACSHA384KeyTemplate(), 41 cbchmacaead.AES256CBCHMACSHA384KeyTemplate(), 42 cbchmacaead.AES256CBCHMACSHA512KeyTemplate(), 43 }, 44 []int{ 45 chacha20poly1305.KeySize, 46 chacha20poly1305.KeySize, 47 subtlecbchmacaead.AES256Size, 48 subtlecbchmacaead.AES128Size, 49 subtlecbchmacaead.AES128Size * twoKeys, 50 subtlecbchmacaead.AES192Size * twoKeys, 51 subtlecbchmacaead.AES256Size + subtlecbchmacaead.AES192Size, 52 subtlecbchmacaead.AES256Size * twoKeys, 53 } 54 } 55 56 func TestCipherGetters(t *testing.T) { 57 keyTemplates, _ := newKeyTemplates() 58 59 for _, c := range keyTemplates { 60 rDem, err := NewRegisterCompositeAEADEncHelper(c) 61 require.NoError(t, err, "error generating a content encryption helper") 62 63 switch rDem.encKeyURL { 64 case AESCBCHMACAEADTypeURL: 65 require.EqualValues(t, subtlecbchmacaead.AESCBCIVSize, rDem.GetIVSize()) 66 67 format := new(aeadpb.AesCbcHmacAeadKeyFormat) 68 err = proto.Unmarshal(c.Value, format) 69 require.NoError(t, err) 70 71 require.EqualValues(t, format.HmacKeyFormat.Params.TagSize, rDem.GetTagSize()) 72 case AESGCMTypeURL: 73 require.EqualValues(t, subtleaead.AESGCMIVSize, rDem.GetIVSize()) 74 require.EqualValues(t, subtleaead.AESGCMTagSize, rDem.GetTagSize()) 75 case ChaCha20Poly1305TypeURL: 76 require.EqualValues(t, chacha20poly1305.NonceSize, rDem.GetIVSize()) 77 require.EqualValues(t, poly1305.TagSize, rDem.GetTagSize()) 78 case XChaCha20Poly1305TypeURL: 79 require.EqualValues(t, chacha20poly1305.NonceSizeX, rDem.GetIVSize()) 80 require.EqualValues(t, poly1305.TagSize, rDem.GetTagSize()) 81 } 82 } 83 } 84 85 func TestCipherGettersFailures(t *testing.T) { 86 tests := []struct { 87 name string 88 typeURL string 89 formatName string 90 }{ 91 { 92 name: "AESCBCHMAC AEAD error", 93 typeURL: AESCBCHMACAEADTypeURL, 94 formatName: "cbcHMACKeyFormat", 95 }, 96 { 97 name: "AESGCM AEAD error", 98 typeURL: AESGCMTypeURL, 99 formatName: "gcmKeyFormat", 100 }, 101 { 102 name: "C20P AEAD error", 103 typeURL: ChaCha20Poly1305TypeURL, 104 formatName: "chachaKeyFormat", 105 }, 106 { 107 name: "XC20P AEAD error", 108 typeURL: XChaCha20Poly1305TypeURL, 109 formatName: "xChachaKeyFormat", 110 }, 111 } 112 113 t.Parallel() 114 115 for _, tt := range tests { 116 tc := tt 117 t.Run(tc.name, func(t *testing.T) { 118 c := &tinkpb.KeyTemplate{ 119 TypeUrl: tc.typeURL, 120 Value: []byte("bad serialized key"), 121 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 122 } 123 124 rDem, err := NewRegisterCompositeAEADEncHelper(c) 125 require.Error(t, err) 126 require.Contains(t, err.Error(), fmt.Sprintf("compositeAEADEncHelper: failed to unmarshal %s", tc.formatName)) 127 require.Empty(t, rDem) 128 }) 129 } 130 } 131 132 func TestUnsupportedKeyTemplates(t *testing.T) { 133 uTemplates := []*tinkpb.KeyTemplate{ 134 signature.ECDSAP256KeyTemplate(), 135 mac.HMACSHA256Tag256KeyTemplate(), 136 {TypeUrl: "some url", Value: []byte{0}}, 137 {TypeUrl: AESGCMTypeURL}, 138 {TypeUrl: AESGCMTypeURL, Value: []byte("123")}, 139 } 140 141 for _, l := range uTemplates { 142 _, err := NewRegisterCompositeAEADEncHelper(l) 143 require.Errorf(t, err, "unsupported key template %s should have generated error: %v", l) 144 } 145 } 146 147 func TestAead(t *testing.T) { 148 keyTemplates, keysSizes := newKeyTemplates() 149 150 for i, c := range keyTemplates { 151 pt := random.GetRandomBytes(20) 152 ad := random.GetRandomBytes(20) 153 rEnc, err := NewRegisterCompositeAEADEncHelper(c) 154 require.NoError(t, err, "error generating a content encryption helper") 155 156 keySize := uint32(keysSizes[i]) 157 sk := random.GetRandomBytes(keySize) 158 a, err := rEnc.GetAEAD(sk) 159 require.NoError(t, err, "error getting AEAD primitive") 160 161 ct, err := a.Encrypt(pt, ad) 162 require.NoError(t, err, "error encrypting") 163 164 dt, err := a.Decrypt(ct, ad) 165 require.NoError(t, err, "error decrypting") 166 167 require.EqualValuesf(t, pt, dt, "decryption not inverse of encryption,\n want :%s,\n got: %s", 168 hex.Dump(pt), hex.Dump(dt)) 169 170 // shorter symmetric key 171 sk = random.GetRandomBytes(keySize - 1) 172 _, err = rEnc.GetAEAD(sk) 173 require.Error(t, err, "retrieving AEAD primitive should have failed") 174 175 // longer symmetric key 176 sk = random.GetRandomBytes(keySize + 1) 177 _, err = rEnc.GetAEAD(sk) 178 require.Error(t, err, "retrieving AEAD primitive should have failed") 179 180 // set bad keyData 181 tmpKeyData := rEnc.keyData 182 rEnc.keyData = []byte{0, 1, 3} 183 sk = random.GetRandomBytes(keySize) 184 _, err = rEnc.GetAEAD(sk) 185 require.Error(t, err, "retrieving AEAD primitive should have failed") 186 187 // set bad key URL 188 rEnc.keyData = tmpKeyData 189 rEnc.encKeyURL = "bad.url" 190 _, err = rEnc.GetAEAD(sk) 191 require.Error(t, err, "retrieving AEAD primitive should have failed") 192 } 193 } 194 195 func TestBuildEncDecData(t *testing.T) { 196 rEnc, err := NewRegisterCompositeAEADEncHelper(aead.AES256GCMKeyTemplate()) 197 require.NoError(t, err) 198 199 refEncData := &EncryptedData{ 200 IV: random.GetRandomBytes(uint32(rEnc.GetIVSize())), 201 Ciphertext: []byte("ciphertext"), 202 Tag: random.GetRandomBytes(uint32(rEnc.GetTagSize())), 203 } 204 205 preBuiltCT := append(refEncData.IV, refEncData.Ciphertext...) 206 preBuiltCT = append(preBuiltCT, refEncData.Tag...) 207 208 // test BuildDecData 209 finalCT := rEnc.BuildDecData(refEncData) 210 require.EqualValues(t, preBuiltCT, finalCT) 211 212 // test BuildEncData 213 mEncData, err := rEnc.BuildEncData(preBuiltCT) 214 require.NoError(t, err) 215 216 mRefEncData, err := json.Marshal(refEncData) 217 require.NoError(t, err) 218 require.EqualValues(t, mRefEncData, mEncData) 219 }