1// Copyright 2022 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 streamingprf_test 18 19import ( 20 "bytes" 21 "testing" 22 23 "google.golang.org/protobuf/proto" 24 "github.com/google/tink/go/aead" 25 "github.com/google/tink/go/core/registry" 26 "github.com/google/tink/go/keyderivation/internal/streamingprf" 27 "github.com/google/tink/go/keyset" 28 "github.com/google/tink/go/prf" 29 "github.com/google/tink/go/subtle/random" 30 "github.com/google/tink/go/testkeyset" 31 commonpb "github.com/google/tink/go/proto/common_go_proto" 32 hkdfpb "github.com/google/tink/go/proto/hkdf_prf_go_proto" 33 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 34) 35 36func TestNew(t *testing.T) { 37 keyData, err := registry.NewKeyData(prf.HKDFSHA256PRFKeyTemplate()) 38 if err != nil { 39 t.Fatalf("registry.NewKeyData() err = %v", err) 40 } 41 ks := &tinkpb.Keyset{ 42 PrimaryKeyId: 119, 43 Key: []*tinkpb.Keyset_Key{ 44 &tinkpb.Keyset_Key{ 45 KeyData: keyData, 46 Status: tinkpb.KeyStatusType_ENABLED, 47 KeyId: 119, 48 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 49 }, 50 }, 51 } 52 handle, err := testkeyset.NewHandle(ks) 53 if err != nil { 54 t.Fatalf("testkeyset.NewHandle(ks) err = %v, want nil", err) 55 } 56 prf, err := streamingprf.New(handle) 57 if err != nil { 58 t.Fatalf("streamingprf.New() err = %v, want nil", err) 59 } 60 r, err := prf.Compute(random.GetRandomBytes(32)) 61 if err != nil { 62 t.Fatalf("prf.Compute() err = %v, want nil", err) 63 } 64 limit := limitFromHash(t, commonpb.HashType_SHA256) 65 out := make([]byte, limit) 66 n, err := r.Read(out) 67 if n != limit || err != nil { 68 t.Errorf("Read() bytes = %d, want %d: %v", n, limit, err) 69 } 70} 71 72func TestNewEqualToStreamingPRFPrimitive(t *testing.T) { 73 streamingPRFKM := streamingprf.HKDFStreamingPRFKeyManager{} 74 prfKM, err := registry.GetKeyManager(hkdfPRFTypeURL) 75 if err != nil { 76 t.Fatalf("GetKeyManager(%s) err = %v, want nil", hkdfPRFTypeURL, err) 77 } 78 for _, test := range []struct { 79 name string 80 hash commonpb.HashType 81 salt []byte 82 }{ 83 { 84 name: "SHA256_nil_salt", 85 hash: commonpb.HashType_SHA256, 86 }, 87 { 88 name: "SHA256_random_salt", 89 hash: commonpb.HashType_SHA256, 90 salt: random.GetRandomBytes(16), 91 }, 92 { 93 name: "SHA512_nil_salt", 94 hash: commonpb.HashType_SHA512, 95 }, 96 { 97 name: "SHA512_random_salt", 98 hash: commonpb.HashType_SHA512, 99 salt: random.GetRandomBytes(16), 100 }, 101 } { 102 t.Run(test.name, func(t *testing.T) { 103 // Construct shared key data. 104 keyFormat := &hkdfpb.HkdfPrfKeyFormat{ 105 Params: &hkdfpb.HkdfPrfParams{ 106 Hash: test.hash, 107 Salt: test.salt, 108 }, 109 KeySize: 32, 110 Version: 0, 111 } 112 serializedKeyFormat, err := proto.Marshal(keyFormat) 113 if err != nil { 114 t.Fatalf("proto.Marshal(%v) err = %v, want nil", keyFormat, err) 115 } 116 sharedKeyData, err := prfKM.NewKeyData(serializedKeyFormat) 117 if err != nil { 118 t.Fatalf("NewKeyData() err = %v, want nil", err) 119 } 120 121 // Use shared key data to create StreamingPRF using New(). 122 var primaryKeyID uint32 = 12 123 handle, err := testkeyset.NewHandle( 124 &tinkpb.Keyset{ 125 PrimaryKeyId: primaryKeyID, 126 Key: []*tinkpb.Keyset_Key{ 127 &tinkpb.Keyset_Key{ 128 KeyData: sharedKeyData, 129 Status: tinkpb.KeyStatusType_ENABLED, 130 KeyId: primaryKeyID, 131 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 132 }, 133 }, 134 }) 135 if err != nil { 136 t.Fatalf("testkeyset.NewHandle() err = %v, want nil", err) 137 } 138 gotPRF, err := streamingprf.New(handle) 139 if err != nil { 140 t.Fatalf("streamingprf.New() err = %v, want nil", err) 141 } 142 143 // Use shared key data to create StreamingPRF using Primitive(). 144 p, err := streamingPRFKM.Primitive(sharedKeyData.GetValue()) 145 if err != nil { 146 t.Fatalf("Primitive() err = %v, want nil", err) 147 } 148 wantPRF, ok := p.(streamingprf.StreamingPRF) 149 if !ok { 150 t.Fatal("primitive is not StreamingPRF") 151 } 152 153 // Verify both PRFs return the same results. 154 limit := limitFromHash(t, test.hash) 155 got, want := make([]byte, limit), make([]byte, limit) 156 data := random.GetRandomBytes(32) 157 { 158 r, err := gotPRF.Compute(data) 159 if err != nil { 160 t.Fatalf("Compute() err = %v, want nil", err) 161 } 162 n, err := r.Read(got) 163 if n != limit || err != nil { 164 t.Fatalf("Read() bytes = %d, want %d: %v", n, limit, err) 165 } 166 } 167 { 168 r, err := wantPRF.Compute(data) 169 if err != nil { 170 t.Fatalf("Compute() err = %v, want nil", err) 171 } 172 n, err := r.Read(want) 173 if n != limit || err != nil { 174 t.Fatalf("Read() bytes = %d, want %d: %v", n, limit, err) 175 } 176 } 177 if !bytes.Equal(got, want) { 178 t.Errorf("Read() = %v, want %v", got, want) 179 } 180 }) 181 } 182} 183 184func TestNewRejectsIncorrectKeysetHandle(t *testing.T) { 185 if _, err := streamingprf.New(nil); err == nil { 186 t.Error("streamingprf.New() err = nil, want non-nil") 187 } 188 189 aeadHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) 190 if err != nil { 191 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 192 } 193 if _, err := streamingprf.New(aeadHandle); err == nil { 194 t.Error("streamingprf.New() err = nil, want non-nil") 195 } 196} 197 198func TestNewRejectsInvalidKeysetHandle(t *testing.T) { 199 keyData, err := registry.NewKeyData(prf.HKDFSHA256PRFKeyTemplate()) 200 if err != nil { 201 t.Fatalf("registry.NewKeyData() err = %v", err) 202 } 203 for _, test := range []struct { 204 name string 205 keyset *tinkpb.Keyset 206 }{ 207 { 208 "multiple raw keys", 209 &tinkpb.Keyset{ 210 PrimaryKeyId: 119, 211 Key: []*tinkpb.Keyset_Key{ 212 &tinkpb.Keyset_Key{ 213 KeyData: keyData, 214 Status: tinkpb.KeyStatusType_ENABLED, 215 KeyId: 119, 216 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 217 }, 218 &tinkpb.Keyset_Key{ 219 KeyData: keyData, 220 Status: tinkpb.KeyStatusType_ENABLED, 221 KeyId: 200, 222 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 223 }, 224 }, 225 }, 226 }, 227 { 228 "various output prefix keys", 229 &tinkpb.Keyset{ 230 PrimaryKeyId: 119, 231 Key: []*tinkpb.Keyset_Key{ 232 &tinkpb.Keyset_Key{ 233 KeyData: keyData, 234 Status: tinkpb.KeyStatusType_ENABLED, 235 KeyId: 119, 236 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 237 }, 238 &tinkpb.Keyset_Key{ 239 KeyData: keyData, 240 Status: tinkpb.KeyStatusType_ENABLED, 241 KeyId: 200, 242 OutputPrefixType: tinkpb.OutputPrefixType_TINK, 243 }, 244 }, 245 }, 246 }, 247 { 248 "invalid prefix type", 249 &tinkpb.Keyset{ 250 PrimaryKeyId: 119, 251 Key: []*tinkpb.Keyset_Key{ 252 &tinkpb.Keyset_Key{ 253 KeyData: keyData, 254 Status: tinkpb.KeyStatusType_ENABLED, 255 KeyId: 119, 256 OutputPrefixType: tinkpb.OutputPrefixType_TINK, 257 }, 258 }, 259 }}, 260 { 261 "invalid status", 262 &tinkpb.Keyset{ 263 PrimaryKeyId: 119, 264 Key: []*tinkpb.Keyset_Key{ 265 &tinkpb.Keyset_Key{ 266 KeyData: keyData, 267 Status: tinkpb.KeyStatusType_UNKNOWN_STATUS, 268 KeyId: 119, 269 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 270 }, 271 }, 272 }, 273 }, 274 { 275 "no primary key", 276 &tinkpb.Keyset{ 277 PrimaryKeyId: 200, 278 Key: []*tinkpb.Keyset_Key{ 279 &tinkpb.Keyset_Key{ 280 KeyData: keyData, 281 Status: tinkpb.KeyStatusType_UNKNOWN_STATUS, 282 KeyId: 119, 283 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 284 }, 285 }, 286 }, 287 }, 288 } { 289 t.Run(test.name, func(t *testing.T) { 290 handle, err := testkeyset.NewHandle(test.keyset) 291 if err != nil { 292 t.Fatalf("testkeyset.NewHandle(test.keyset) err = %v, want nil", err) 293 } 294 if _, err := streamingprf.New(handle); err == nil { 295 t.Error("streamingprf.New() err = nil, want non-nil") 296 } 297 }) 298 } 299} 300