1// Copyright 2020 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package subtle_test 18 19import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "testing" 24 25 "github.com/google/tink/go/prf/subtle" 26 "github.com/google/tink/go/testutil" 27) 28 29func TestVectorsRFC4493(t *testing.T) { 30 // Test vectors from RFC 4493. 31 key, err := hex.DecodeString("2b7e151628aed2a6abf7158809cf4f3c") 32 if err != nil { 33 t.Errorf("Could not decode key: %v", err) 34 } 35 data, err := hex.DecodeString("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710") 36 if err != nil { 37 t.Errorf("Could not decode data: %v", err) 38 } 39 expected := map[int]string{ 40 0: "bb1d6929e95937287fa37d129b756746", 41 16: "070a16b46b4d4144f79bdd9dd04a287c", 42 40: "dfa66747de9ae63030ca32611497c827", 43 64: "51f0bebf7e3b9d92fc49741779363cfe", 44 } 45 a, err := subtle.NewAESCMACPRF(key) 46 if err != nil { 47 t.Errorf("Could not create cmac.AES object: %v", err) 48 } 49 for l, e := range expected { 50 output, err := a.ComputePRF(data[:l], 16) 51 if err != nil { 52 t.Errorf("Error computing AES-CMAC: %v", err) 53 } 54 if hex.EncodeToString(output) != e { 55 t.Errorf("Computation and test vector differ. Computation: %q, Test Vector %q", hex.EncodeToString(output), e) 56 } 57 } 58} 59 60func TestAESCMACPRFWycheproofCases(t *testing.T) { 61 testutil.SkipTestIfTestSrcDirIsNotSet(t) 62 suite := new(macSuite) 63 if err := testutil.PopulateSuite(suite, "aes_cmac_test.json"); err != nil { 64 t.Fatalf("Failed populating suite: %s", err) 65 } 66 for _, group := range suite.TestGroups { 67 groupName := fmt.Sprintf("%s-%s(%d)", suite.Algorithm, group.Type, group.KeySize) 68 if group.TagSize%8 != 0 { 69 t.Errorf("For %s, requested tag size is not a multiple of 8, but %d", groupName, group.TagSize) 70 continue 71 } 72 73 for _, test := range group.Tests { 74 caseName := fmt.Sprintf("%s:Case-%d", groupName, test.CaseID) 75 t.Run(caseName, func(t *testing.T) { 76 if uint32(len(test.Key))*8 != group.KeySize { 77 t.Fatalf("Invalid key length: %s", test.Comment) 78 } 79 80 aes, err := subtle.NewAESCMACPRF(test.Key) 81 switch test.Result { 82 case "valid": 83 if err != nil { 84 t.Fatalf("NewAESCMACPRF failed (case: %s): %v", test.Comment, err) 85 } 86 res, err := aes.ComputePRF(test.Message, group.TagSize/8) 87 if err != nil { 88 t.Fatalf("ComputePRF() failed: %v", err) 89 } 90 if !bytes.Equal(res, test.Tag) { 91 t.Errorf("ComputePRF() result and expected result do not match:\nComputed: %q\nExpected: %q", hex.EncodeToString(res), test.Tag) 92 } 93 94 case "invalid": 95 if err != nil { 96 return 97 } 98 res, err := aes.ComputePRF(test.Message, group.TagSize/8) 99 if err != nil { 100 return 101 } 102 if bytes.Equal(res, test.Tag) { 103 t.Errorf("ComputePRF() result and invalid expected result match:\nComputed: %q\nExpected: %q", hex.EncodeToString(res), test.Tag) 104 } 105 106 default: 107 t.Fatalf("Unsupported test result: %q", test.Result) 108 } 109 }) 110 } 111 } 112} 113 114func TestValidateAESCMACPRFParams(t *testing.T) { 115 if err := subtle.ValidateAESCMACPRFParams(32); err != nil { 116 t.Errorf("Unexpected error validating AES CMAC PRF Params: %v", err) 117 } 118 if err := subtle.ValidateAESCMACPRFParams(2); err == nil { 119 t.Errorf("Unexpected validation of too short key for AES CMAC PRF Params") 120 } 121} 122 123func TestKeyLength(t *testing.T) { 124 if _, err := subtle.NewAESCMACPRF([]byte{0x01, 0x02}); err == nil { 125 t.Errorf("Expected NewAESCMACPRF to fail on short key") 126 } 127 if _, err := subtle.NewAESCMACPRF([]byte{ 128 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 129 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}); err != nil { 130 t.Errorf("Expected NewAESCMACPRF to work on 16 byte key") 131 } 132 if _, err := subtle.NewAESCMACPRF([]byte{ 133 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 134 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 135 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 136 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}); err != nil { 137 t.Errorf("Expected NewAESCMACPRF to work on 32 byte key") 138 } 139} 140 141func TestAESCMACPRFOutputLength(t *testing.T) { 142 prf, err := subtle.NewAESCMACPRF([]byte{ 143 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 144 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 145 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 146 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}) 147 if err != nil { 148 t.Errorf("Expected NewAESCMACPRF to work on 32 byte key") 149 } 150 for i := 0; i <= 16; i++ { 151 output, err := prf.ComputePRF([]byte{0x01, 0x02}, uint32(i)) 152 if err != nil { 153 t.Errorf("Expected to be able to compute AES CMAC PRF with %d output length", i) 154 } 155 if len(output) != i { 156 t.Errorf("Expected AES CMAC PRF to compute %d bytes, got %d", i, len(output)) 157 } 158 } 159 for i := 17; i < 32; i++ { 160 _, err := prf.ComputePRF([]byte{0x01, 0x02}, uint32(i)) 161 if err == nil { 162 t.Errorf("Expected to not be able to compute AES CMAC PRF with %d output length", i) 163 } 164 } 165} 166