1// Copyright 2018 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 17// Package testutil provides common methods needed in test code. 18package testutil 19 20import ( 21 "bytes" 22 "crypto/ecdsa" 23 "crypto/ed25519" 24 "crypto/rand" 25 "encoding/gob" 26 "errors" 27 "fmt" 28 "log" 29 "math" 30 "strconv" 31 "strings" 32 33 "google.golang.org/protobuf/proto" 34 "github.com/google/tink/go/core/registry" 35 subtledaead "github.com/google/tink/go/daead/subtle" 36 subtlehybrid "github.com/google/tink/go/hybrid/subtle" 37 "github.com/google/tink/go/keyset" 38 "github.com/google/tink/go/mac" 39 "github.com/google/tink/go/subtle/random" 40 "github.com/google/tink/go/subtle" 41 "github.com/google/tink/go/tink" 42 43 cmacpb "github.com/google/tink/go/proto/aes_cmac_go_proto" 44 aescmacprfpb "github.com/google/tink/go/proto/aes_cmac_prf_go_proto" 45 ctrhmacpb "github.com/google/tink/go/proto/aes_ctr_hmac_streaming_go_proto" 46 gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" 47 gcmhkdfpb "github.com/google/tink/go/proto/aes_gcm_hkdf_streaming_go_proto" 48 gcmsivpb "github.com/google/tink/go/proto/aes_gcm_siv_go_proto" 49 aspb "github.com/google/tink/go/proto/aes_siv_go_proto" 50 commonpb "github.com/google/tink/go/proto/common_go_proto" 51 ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto" 52 eciespb "github.com/google/tink/go/proto/ecies_aead_hkdf_go_proto" 53 ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto" 54 hkdfprfpb "github.com/google/tink/go/proto/hkdf_prf_go_proto" 55 hmacpb "github.com/google/tink/go/proto/hmac_go_proto" 56 hmacprfpb "github.com/google/tink/go/proto/hmac_prf_go_proto" 57 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 58) 59 60// DummyAEADKeyManager is a dummy implementation of the KeyManager interface. 61// It returns DummyAEAD when GetPrimitive() functions are called. 62type DummyAEADKeyManager struct{} 63 64var _ registry.KeyManager = (*DummyAEADKeyManager)(nil) 65 66// Primitive constructs a primitive instance for the key given in 67// serializedKey, which must be a serialized key protocol buffer handled by this manager. 68func (km *DummyAEADKeyManager) Primitive(serializedKey []byte) (interface{}, error) { 69 return new(DummyAEAD), nil 70} 71 72// NewKey generates a new key according to specification in serializedKeyFormat. 73func (km *DummyAEADKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { 74 return nil, fmt.Errorf("not implemented") 75} 76 77// NewKeyData generates a new KeyData according to specification in serializedkeyFormat. 78func (km *DummyAEADKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { 79 return nil, fmt.Errorf("not implemented") 80} 81 82// DoesSupport returns true iff this KeyManager supports key type identified by typeURL. 83func (km *DummyAEADKeyManager) DoesSupport(typeURL string) bool { 84 return typeURL == AESGCMTypeURL 85} 86 87// TypeURL returns the type URL. 88func (km *DummyAEADKeyManager) TypeURL() string { 89 return AESGCMTypeURL 90} 91 92// DummyAEAD is a dummy implementation of AEAD interface. It "encrypts" data 93// with a simple serialization capturing the dummy name, plaintext, and 94// associated data, and "decrypts" it by reversing this and checking that the 95// name and associated data match. 96type DummyAEAD struct { 97 Name string 98} 99 100type dummyAEADData struct { 101 Name string 102 Plaintext []byte 103 AssociatedData []byte 104} 105 106// Encrypt encrypts the plaintext. 107func (a *DummyAEAD) Encrypt(plaintext []byte, associatedData []byte) ([]byte, error) { 108 buf := new(bytes.Buffer) 109 encoder := gob.NewEncoder(buf) 110 err := encoder.Encode(dummyAEADData{ 111 Name: a.Name, 112 Plaintext: plaintext, 113 AssociatedData: associatedData, 114 }) 115 if err != nil { 116 return nil, fmt.Errorf("dummy aead encrypt: %v", err) 117 } 118 return buf.Bytes(), nil 119} 120 121// Decrypt decrypts the ciphertext. 122func (a *DummyAEAD) Decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) { 123 data := dummyAEADData{} 124 decoder := gob.NewDecoder(bytes.NewBuffer(ciphertext)) 125 if err := decoder.Decode(&data); err != nil { 126 return nil, fmt.Errorf("dummy aead decrypt: invalid data: %v", err) 127 } 128 if data.Name != a.Name || !bytes.Equal(data.AssociatedData, associatedData) { 129 return nil, errors.New("dummy aead encrypt: name/associated data mismatch") 130 } 131 return data.Plaintext, nil 132} 133 134// AlwaysFailingAead fails encryption and decryption operations. 135type AlwaysFailingAead struct { 136 Error error 137} 138 139var _ (tink.AEAD) = (*AlwaysFailingAead)(nil) 140 141// NewAlwaysFailingAead creates a new always failing AEAD. 142func NewAlwaysFailingAead(err error) tink.AEAD { 143 return &AlwaysFailingAead{Error: err} 144} 145 146// Encrypt returns an error on encryption. 147func (a *AlwaysFailingAead) Encrypt(plaintext []byte, associatedData []byte) ([]byte, error) { 148 return nil, fmt.Errorf("AlwaysFailingAead will always fail on encryption: %v", a.Error) 149} 150 151// Decrypt returns an error on decryption. 152func (a *AlwaysFailingAead) Decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) { 153 return nil, fmt.Errorf("AlwaysFailingAead will always fail on decryption: %v", a.Error) 154} 155 156// AlwaysFailingDeterministicAead fails encryption and decryption operations. 157type AlwaysFailingDeterministicAead struct { 158 Error error 159} 160 161var _ (tink.DeterministicAEAD) = (*AlwaysFailingDeterministicAead)(nil) 162 163// NewAlwaysFailingDeterministicAead creates a new always failing AEAD. 164func NewAlwaysFailingDeterministicAead(err error) tink.DeterministicAEAD { 165 return &AlwaysFailingDeterministicAead{Error: err} 166} 167 168// EncryptDeterministically returns an error on encryption. 169func (a *AlwaysFailingDeterministicAead) EncryptDeterministically(plaintext []byte, associatedData []byte) ([]byte, error) { 170 return nil, fmt.Errorf("AlwaysFailingDeterministicAead will always fail on encryption: %v", a.Error) 171} 172 173// DecryptDeterministically returns an error on decryption. 174func (a *AlwaysFailingDeterministicAead) DecryptDeterministically(ciphertext []byte, associatedData []byte) ([]byte, error) { 175 return nil, fmt.Errorf("AlwaysFailingDeterministicAead will always fail on decryption: %v", a.Error) 176} 177 178// TestKeyManager is key manager which can be setup to return an arbitrary primitive for a type URL 179// useful for testing. 180type TestKeyManager struct { 181 primitive interface{} 182 typeURL string 183} 184 185var _ registry.KeyManager = (*TestKeyManager)(nil) 186 187// NewTestKeyManager creates a new key manager that returns a specific primitive for a typeURL. 188func NewTestKeyManager(primitive interface{}, typeURL string) registry.KeyManager { 189 return &TestKeyManager{ 190 primitive: primitive, 191 typeURL: typeURL, 192 } 193} 194 195// Primitive constructs a primitive instance for the key given input key. 196func (km *TestKeyManager) Primitive(serializedKey []byte) (interface{}, error) { 197 return km.primitive, nil 198} 199 200// NewKey generates a new key according to specification in serializedKeyFormat. 201func (km *TestKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { 202 return nil, fmt.Errorf("TestKeyManager: not implemented") 203} 204 205// NewKeyData generates a new KeyData according to specification in serializedkeyFormat. 206func (km *TestKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { 207 return nil, fmt.Errorf("TestKeyManager: not implemented") 208} 209 210// DoesSupport returns true if this KeyManager supports key type identified by typeURL. 211func (km *TestKeyManager) DoesSupport(typeURL string) bool { 212 return typeURL == km.typeURL 213} 214 215// TypeURL returns the type URL. 216func (km *TestKeyManager) TypeURL() string { 217 return km.typeURL 218} 219 220// DummySigner is a dummy implementation of the Signer interface. 221type DummySigner struct { 222 aead DummyAEAD 223} 224 225// NewDummySigner creates a new dummy signer with the specified name. The name 226// is used to pair with the DummyVerifier. 227func NewDummySigner(name string) *DummySigner { 228 return &DummySigner{DummyAEAD{Name: "dummy public key:" + name}} 229} 230 231// Sign signs data. 232func (s *DummySigner) Sign(data []byte) ([]byte, error) { 233 return s.aead.Encrypt(nil, data) 234} 235 236// DummyVerifier is a dummy implementation of the Signer interface. 237type DummyVerifier struct { 238 aead DummyAEAD 239} 240 241// Verify verifies data. 242func (v *DummyVerifier) Verify(sig, data []byte) error { 243 _, err := v.aead.Decrypt(sig, data) 244 return err 245} 246 247// NewDummyVerifier creates a new dummy verifier with the specified name. The 248// name is used to pair with the DummySigner. 249func NewDummyVerifier(name string) *DummyVerifier { 250 return &DummyVerifier{DummyAEAD{Name: "dummy public key:" + name}} 251} 252 253// DummyMAC is a dummy implementation of Mac interface. 254type DummyMAC struct { 255 Name string 256} 257 258// ComputeMAC computes a message authentication code (MAC) for data. 259func (h *DummyMAC) ComputeMAC(data []byte) ([]byte, error) { 260 var m []byte 261 m = append(m, data...) 262 m = append(m, h.Name...) 263 return m, nil 264} 265 266// VerifyMAC verifies whether mac is a correct message authentication code 267// (MAC) for data. 268func (h *DummyMAC) VerifyMAC(mac []byte, data []byte) error { 269 return nil 270} 271 272// DummyKMSClient is a dummy implementation of a KMS Client. 273type DummyKMSClient struct{} 274 275var _ registry.KMSClient = (*DummyKMSClient)(nil) 276 277// Supported true if this client does support keyURI 278func (d *DummyKMSClient) Supported(keyURI string) bool { 279 return keyURI == "dummy" 280} 281 282// GetAEAD gets an Aead backend by keyURI. 283func (d *DummyKMSClient) GetAEAD(keyURI string) (tink.AEAD, error) { 284 return &DummyAEAD{}, nil 285} 286 287// NewTestAESGCMKeyset creates a new Keyset containing an AESGCMKey. 288func NewTestAESGCMKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset { 289 keyData := NewAESGCMKeyData(16) 290 return NewTestKeyset(keyData, primaryOutputPrefixType) 291} 292 293// NewTestAESGCMSIVKeyset creates a new Keyset containing an AESGCMSIVKey. 294func NewTestAESGCMSIVKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset { 295 keyData := NewAESGCMSIVKeyData(16) 296 return NewTestKeyset(keyData, primaryOutputPrefixType) 297} 298 299// NewTestAESSIVKeyset creates a new Keyset containing an AesSivKey. 300func NewTestAESSIVKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset { 301 keyValue := random.GetRandomBytes(subtledaead.AESSIVKeySize) 302 key := &aspb.AesSivKey{ 303 Version: AESSIVKeyVersion, 304 KeyValue: keyValue, 305 } 306 serializedKey, err := proto.Marshal(key) 307 if err != nil { 308 log.Fatalf("failed serializing proto: %v", err) 309 } 310 keyData := NewKeyData(AESSIVTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC) 311 return NewTestKeyset(keyData, primaryOutputPrefixType) 312} 313 314// NewTestHMACKeyset creates a new Keyset containing a HMACKey. 315func NewTestHMACKeyset(tagSize uint32, primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset { 316 keyData := NewHMACKeyData(commonpb.HashType_SHA256, tagSize) 317 return NewTestKeyset(keyData, primaryOutputPrefixType) 318} 319 320// NewTestAESGCMHKDFKeyset creates a new Keyset containing an AESGCMHKDFKey. 321func NewTestAESGCMHKDFKeyset() *tinkpb.Keyset { 322 const ( 323 keySize = 16 324 derivedKeySize = 16 325 ciphertextSegmentSize = 4096 326 ) 327 keyData := NewAESGCMHKDFKeyData(keySize, derivedKeySize, commonpb.HashType_SHA256, ciphertextSegmentSize) 328 return NewTestKeyset(keyData, tinkpb.OutputPrefixType_RAW) 329} 330 331// NewTestKeyset creates a new test Keyset. 332func NewTestKeyset(keyData *tinkpb.KeyData, primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset { 333 primaryKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 42, primaryOutputPrefixType) 334 rawKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 43, tinkpb.OutputPrefixType_RAW) 335 legacyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 44, tinkpb.OutputPrefixType_LEGACY) 336 tinkKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 45, tinkpb.OutputPrefixType_TINK) 337 crunchyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 46, tinkpb.OutputPrefixType_CRUNCHY) 338 keys := []*tinkpb.Keyset_Key{primaryKey, rawKey, legacyKey, tinkKey, crunchyKey} 339 return NewKeyset(primaryKey.KeyId, keys) 340} 341 342// NewDummyKey returns a dummy key that doesn't contain actual key material. 343func NewDummyKey(keyID int, status tinkpb.KeyStatusType, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key { 344 return &tinkpb.Keyset_Key{ 345 KeyData: new(tinkpb.KeyData), 346 Status: status, 347 KeyId: uint32(keyID), 348 OutputPrefixType: outputPrefixType, 349 } 350} 351 352// NewECDSAParams creates a ECDSAParams with the specified parameters. 353func NewECDSAParams(hashType commonpb.HashType, curve commonpb.EllipticCurveType, encoding ecdsapb.EcdsaSignatureEncoding) *ecdsapb.EcdsaParams { 354 return &ecdsapb.EcdsaParams{ 355 HashType: hashType, 356 Curve: curve, 357 Encoding: encoding, 358 } 359} 360 361// NewECDSAKeyFormat creates a ECDSAKeyFormat with the specified parameters. 362func NewECDSAKeyFormat(params *ecdsapb.EcdsaParams) *ecdsapb.EcdsaKeyFormat { 363 return &ecdsapb.EcdsaKeyFormat{Params: params} 364} 365 366// NewECDSAPrivateKey creates a ECDSAPrivateKey with the specified paramaters. 367func NewECDSAPrivateKey(version uint32, publicKey *ecdsapb.EcdsaPublicKey, keyValue []byte) *ecdsapb.EcdsaPrivateKey { 368 return &ecdsapb.EcdsaPrivateKey{ 369 Version: version, 370 PublicKey: publicKey, 371 KeyValue: keyValue, 372 } 373} 374 375// NewECDSAPublicKey creates a ECDSAPublicKey with the specified paramaters. 376func NewECDSAPublicKey(version uint32, params *ecdsapb.EcdsaParams, x, y []byte) *ecdsapb.EcdsaPublicKey { 377 return &ecdsapb.EcdsaPublicKey{ 378 Version: version, 379 Params: params, 380 X: x, 381 Y: y, 382 } 383} 384 385// NewRandomECDSAPrivateKey creates an ECDSAPrivateKey with randomly generated key material. 386func NewRandomECDSAPrivateKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPrivateKey { 387 curveName := commonpb.EllipticCurveType_name[int32(curve)] 388 priv, _ := ecdsa.GenerateKey(subtle.GetCurve(curveName), rand.Reader) 389 params := NewECDSAParams(hashType, curve, ecdsapb.EcdsaSignatureEncoding_DER) 390 publicKey := NewECDSAPublicKey(ECDSAVerifierKeyVersion, params, priv.X.Bytes(), priv.Y.Bytes()) 391 return NewECDSAPrivateKey(ECDSASignerKeyVersion, publicKey, priv.D.Bytes()) 392} 393 394// NewRandomECDSAPublicKey creates an ECDSAPublicKey with randomly generated key material. 395func NewRandomECDSAPublicKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPublicKey { 396 return NewRandomECDSAPrivateKey(hashType, curve).PublicKey 397} 398 399// GetECDSAParamNames returns the string representations of each parameter in 400// the given ECDSAParams. 401func GetECDSAParamNames(params *ecdsapb.EcdsaParams) (string, string, string) { 402 hashName := commonpb.HashType_name[int32(params.HashType)] 403 curveName := commonpb.EllipticCurveType_name[int32(params.Curve)] 404 encodingName := ecdsapb.EcdsaSignatureEncoding_name[int32(params.Encoding)] 405 return hashName, curveName, encodingName 406} 407 408// NewED25519PrivateKey creates an ED25519PrivateKey with randomly generated key material. 409func NewED25519PrivateKey() *ed25519pb.Ed25519PrivateKey { 410 public, private, _ := ed25519.GenerateKey(rand.Reader) 411 publicProto := &ed25519pb.Ed25519PublicKey{ 412 Version: ED25519SignerKeyVersion, 413 KeyValue: public, 414 } 415 return &ed25519pb.Ed25519PrivateKey{ 416 Version: ED25519SignerKeyVersion, 417 PublicKey: publicProto, 418 KeyValue: private.Seed(), 419 } 420} 421 422// NewED25519PublicKey creates an ED25519PublicKey with randomly generated key material. 423func NewED25519PublicKey() *ed25519pb.Ed25519PublicKey { 424 return NewED25519PrivateKey().PublicKey 425} 426 427// NewAESGCMKey creates a randomly generated AESGCMKey. 428func NewAESGCMKey(keyVersion uint32, keySize uint32) *gcmpb.AesGcmKey { 429 keyValue := random.GetRandomBytes(keySize) 430 return &gcmpb.AesGcmKey{ 431 Version: keyVersion, 432 KeyValue: keyValue, 433 } 434} 435 436// NewAESGCMKeyData creates a KeyData containing a randomly generated AESGCMKey. 437func NewAESGCMKeyData(keySize uint32) *tinkpb.KeyData { 438 serializedKey, err := proto.Marshal(NewAESGCMKey(AESGCMKeyVersion, keySize)) 439 if err != nil { 440 log.Fatalf("failed serializing proto: %v", err) 441 } 442 return NewKeyData(AESGCMTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC) 443} 444 445// NewAESGCMKeyFormat returns a new AESGCMKeyFormat. 446func NewAESGCMKeyFormat(keySize uint32) *gcmpb.AesGcmKeyFormat { 447 return &gcmpb.AesGcmKeyFormat{ 448 KeySize: keySize, 449 } 450} 451 452// NewAESGCMSIVKey creates a randomly generated AESGCMSIVKey. 453func NewAESGCMSIVKey(keyVersion, keySize uint32) *gcmsivpb.AesGcmSivKey { 454 keyValue := random.GetRandomBytes(keySize) 455 return &gcmsivpb.AesGcmSivKey{ 456 Version: keyVersion, 457 KeyValue: keyValue, 458 } 459} 460 461// NewAESGCMSIVKeyData creates a KeyData containing a randomly generated AESGCMSIVKey. 462func NewAESGCMSIVKeyData(keySize uint32) *tinkpb.KeyData { 463 serializedKey, err := proto.Marshal(NewAESGCMSIVKey(AESGCMKeyVersion, keySize)) 464 if err != nil { 465 log.Fatalf("NewAESGCMSIVKeyData(keySize=%d): Failed serializing proto; err=%v", keySize, err) 466 } 467 return NewKeyData(AESGCMTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC) 468} 469 470// NewAESGCMSIVKeyFormat returns a new AESGCMKeyFormat. 471func NewAESGCMSIVKeyFormat(keySize uint32) *gcmsivpb.AesGcmSivKeyFormat { 472 return &gcmsivpb.AesGcmSivKeyFormat{ 473 KeySize: keySize, 474 } 475} 476 477// NewAESGCMHKDFKey creates a randomly generated AESGCMHKDFKey. 478func NewAESGCMHKDFKey(keyVersion, keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *gcmhkdfpb.AesGcmHkdfStreamingKey { 479 keyValue := random.GetRandomBytes(keySize) 480 return &gcmhkdfpb.AesGcmHkdfStreamingKey{ 481 Version: keyVersion, 482 KeyValue: keyValue, 483 Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{ 484 CiphertextSegmentSize: ciphertextSegmentSize, 485 DerivedKeySize: derivedKeySize, 486 HkdfHashType: hkdfHashType, 487 }, 488 } 489} 490 491// NewAESGCMHKDFKeyData creates a KeyData containing a randomly generated AESGCMHKDFKey. 492func NewAESGCMHKDFKeyData(keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *tinkpb.KeyData { 493 serializedKey, err := proto.Marshal(NewAESGCMHKDFKey(AESGCMHKDFKeyVersion, keySize, derivedKeySize, hkdfHashType, ciphertextSegmentSize)) 494 if err != nil { 495 log.Fatalf("failed serializing proto: %v", err) 496 } 497 return NewKeyData(AESGCMHKDFTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC) 498} 499 500// NewAESGCMHKDFKeyFormat returns a new AESGCMHKDFKeyFormat. 501func NewAESGCMHKDFKeyFormat(keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *gcmhkdfpb.AesGcmHkdfStreamingKeyFormat { 502 return &gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{ 503 KeySize: keySize, 504 Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{ 505 CiphertextSegmentSize: ciphertextSegmentSize, 506 DerivedKeySize: derivedKeySize, 507 HkdfHashType: hkdfHashType, 508 }, 509 } 510} 511 512// NewAESCTRHMACKey creates a randomly generated AESCTRHMACKey. 513func NewAESCTRHMACKey(keyVersion, keySize uint32, hkdfHashType commonpb.HashType, derivedKeySize uint32, hashType commonpb.HashType, tagSize, ciphertextSegmentSize uint32) *ctrhmacpb.AesCtrHmacStreamingKey { 514 keyValue := random.GetRandomBytes(keySize) 515 return &ctrhmacpb.AesCtrHmacStreamingKey{ 516 Version: keyVersion, 517 KeyValue: keyValue, 518 Params: &ctrhmacpb.AesCtrHmacStreamingParams{ 519 CiphertextSegmentSize: ciphertextSegmentSize, 520 DerivedKeySize: derivedKeySize, 521 HkdfHashType: hkdfHashType, 522 HmacParams: &hmacpb.HmacParams{ 523 Hash: hashType, 524 TagSize: tagSize, 525 }, 526 }, 527 } 528} 529 530// NewAESCTRHMACKeyFormat returns a new AESCTRHMACKeyFormat. 531func NewAESCTRHMACKeyFormat(keySize uint32, hkdfHashType commonpb.HashType, derivedKeySize uint32, hashType commonpb.HashType, tagSize, ciphertextSegmentSize uint32) *ctrhmacpb.AesCtrHmacStreamingKeyFormat { 532 return &ctrhmacpb.AesCtrHmacStreamingKeyFormat{ 533 KeySize: keySize, 534 Params: &ctrhmacpb.AesCtrHmacStreamingParams{ 535 CiphertextSegmentSize: ciphertextSegmentSize, 536 DerivedKeySize: derivedKeySize, 537 HkdfHashType: hkdfHashType, 538 HmacParams: &hmacpb.HmacParams{ 539 Hash: hashType, 540 TagSize: tagSize, 541 }, 542 }, 543 } 544} 545 546// NewHMACParams returns a new HMACParams. 547func NewHMACParams(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacParams { 548 return &hmacpb.HmacParams{ 549 Hash: hashType, 550 TagSize: tagSize, 551 } 552} 553 554// NewHMACKey creates a new HMACKey with the specified parameters. 555func NewHMACKey(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKey { 556 params := NewHMACParams(hashType, tagSize) 557 keyValue := random.GetRandomBytes(20) 558 return &hmacpb.HmacKey{ 559 Version: HMACKeyVersion, 560 Params: params, 561 KeyValue: keyValue, 562 } 563} 564 565// NewHMACKeyFormat creates a new HMACKeyFormat with the specified parameters. 566func NewHMACKeyFormat(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKeyFormat { 567 params := NewHMACParams(hashType, tagSize) 568 keySize := uint32(20) 569 return &hmacpb.HmacKeyFormat{ 570 Params: params, 571 KeySize: keySize, 572 } 573} 574 575// NewAESCMACParams returns a new AESCMACParams. 576func NewAESCMACParams(tagSize uint32) *cmacpb.AesCmacParams { 577 return &cmacpb.AesCmacParams{ 578 TagSize: tagSize, 579 } 580} 581 582// NewAESCMACKey creates a new AESCMACKey with the specified parameters. 583func NewAESCMACKey(tagSize uint32) *cmacpb.AesCmacKey { 584 params := NewAESCMACParams(tagSize) 585 keyValue := random.GetRandomBytes(32) 586 return &cmacpb.AesCmacKey{ 587 Version: AESCMACKeyVersion, 588 Params: params, 589 KeyValue: keyValue, 590 } 591} 592 593// NewAESCMACKeyFormat creates a new AESCMACKeyFormat with the specified parameters. 594func NewAESCMACKeyFormat(tagSize uint32) *cmacpb.AesCmacKeyFormat { 595 params := NewAESCMACParams(tagSize) 596 keySize := uint32(32) 597 return &cmacpb.AesCmacKeyFormat{ 598 Params: params, 599 KeySize: keySize, 600 } 601} 602 603// NewHMACKeysetManager returns a new KeysetManager that contains a HMACKey. 604func NewHMACKeysetManager() *keyset.Manager { 605 ksm := keyset.NewManager() 606 kt := mac.HMACSHA256Tag128KeyTemplate() 607 keyID, err := ksm.Add(kt) 608 if err != nil { 609 panic(fmt.Sprintf("cannot add key: %v", err)) 610 } 611 err = ksm.SetPrimary(keyID) 612 if err != nil { 613 panic(fmt.Sprintf("cannot set primary key: %v", err)) 614 } 615 return ksm 616} 617 618// NewHMACKeyData returns a new KeyData that contains a HMACKey. 619func NewHMACKeyData(hashType commonpb.HashType, tagSize uint32) *tinkpb.KeyData { 620 key := NewHMACKey(hashType, tagSize) 621 serializedKey, err := proto.Marshal(key) 622 if err != nil { 623 log.Fatalf("failed serializing proto: %v", err) 624 } 625 return &tinkpb.KeyData{ 626 TypeUrl: HMACTypeURL, 627 Value: serializedKey, 628 KeyMaterialType: tinkpb.KeyData_SYMMETRIC, 629 } 630} 631 632// NewHMACPRFParams returns a new HMACPRFParams. 633func NewHMACPRFParams(hashType commonpb.HashType) *hmacprfpb.HmacPrfParams { 634 return &hmacprfpb.HmacPrfParams{ 635 Hash: hashType, 636 } 637} 638 639// NewHMACPRFKey creates a new HMACPRFKey with the specified parameters. 640func NewHMACPRFKey(hashType commonpb.HashType) *hmacprfpb.HmacPrfKey { 641 params := NewHMACPRFParams(hashType) 642 keyValue := random.GetRandomBytes(32) 643 return &hmacprfpb.HmacPrfKey{ 644 Version: HMACPRFKeyVersion, 645 Params: params, 646 KeyValue: keyValue, 647 } 648} 649 650// NewHMACPRFKeyFormat creates a new HMACPRFKeyFormat with the specified parameters. 651func NewHMACPRFKeyFormat(hashType commonpb.HashType) *hmacprfpb.HmacPrfKeyFormat { 652 params := NewHMACPRFParams(hashType) 653 keySize := uint32(32) 654 return &hmacprfpb.HmacPrfKeyFormat{ 655 Params: params, 656 KeySize: keySize, 657 } 658} 659 660// NewHKDFPRFParams returns a new HKDFPRFParams. 661func NewHKDFPRFParams(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfParams { 662 return &hkdfprfpb.HkdfPrfParams{ 663 Hash: hashType, 664 Salt: salt, 665 } 666} 667 668// NewHKDFPRFKey creates a new HKDFPRFKey with the specified parameters. 669func NewHKDFPRFKey(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKey { 670 params := NewHKDFPRFParams(hashType, salt) 671 keyValue := random.GetRandomBytes(32) 672 return &hkdfprfpb.HkdfPrfKey{ 673 Version: HKDFPRFKeyVersion, 674 Params: params, 675 KeyValue: keyValue, 676 } 677} 678 679// NewHKDFPRFKeyFormat creates a new HKDFPRFKeyFormat with the specified parameters. 680func NewHKDFPRFKeyFormat(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKeyFormat { 681 params := NewHKDFPRFParams(hashType, salt) 682 keySize := uint32(32) 683 return &hkdfprfpb.HkdfPrfKeyFormat{ 684 Params: params, 685 KeySize: keySize, 686 } 687} 688 689// NewAESCMACPRFKey creates a new AESCMACPRFKey with the specified parameters. 690func NewAESCMACPRFKey() *aescmacprfpb.AesCmacPrfKey { 691 keyValue := random.GetRandomBytes(32) 692 return &aescmacprfpb.AesCmacPrfKey{ 693 Version: AESCMACPRFKeyVersion, 694 KeyValue: keyValue, 695 } 696} 697 698// NewAESCMACPRFKeyFormat creates a new AESCMACPRFKeyFormat with the specified parameters. 699func NewAESCMACPRFKeyFormat() *aescmacprfpb.AesCmacPrfKeyFormat { 700 keySize := uint32(32) 701 return &aescmacprfpb.AesCmacPrfKeyFormat{ 702 KeySize: keySize, 703 } 704} 705 706// NewKeyData creates a new KeyData with the specified parameters. 707func NewKeyData(typeURL string, value []byte, materialType tinkpb.KeyData_KeyMaterialType) *tinkpb.KeyData { 708 return &tinkpb.KeyData{ 709 TypeUrl: typeURL, 710 Value: value, 711 KeyMaterialType: materialType, 712 } 713} 714 715// NewKey creates a new Key with the specified parameters. 716func NewKey(keyData *tinkpb.KeyData, status tinkpb.KeyStatusType, keyID uint32, prefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key { 717 return &tinkpb.Keyset_Key{ 718 KeyData: keyData, 719 Status: status, 720 KeyId: keyID, 721 OutputPrefixType: prefixType, 722 } 723} 724 725// NewKeyset creates a new Keyset with the specified parameters. 726func NewKeyset(primaryKeyID uint32, keys []*tinkpb.Keyset_Key) *tinkpb.Keyset { 727 return &tinkpb.Keyset{ 728 PrimaryKeyId: primaryKeyID, 729 Key: keys, 730 } 731} 732 733// GenerateMutations generates different byte mutations for a given byte array. 734func GenerateMutations(src []byte) (all [][]byte) { 735 // Flip bits 736 for i := 0; i < len(src); i++ { 737 for j := 0; j < 8; j++ { 738 n := make([]byte, len(src)) 739 copy(n, src) 740 n[i] = n[i] ^ (1 << uint8(j)) 741 all = append(all, n) 742 } 743 } 744 745 //truncate bytes 746 for i := 1; i < len(src); i++ { 747 n := make([]byte, len(src[i:])) 748 copy(n, src[i:]) 749 all = append(all, n) 750 } 751 752 //append extra byte 753 m := make([]byte, len(src)+1) 754 copy(m, src) 755 all = append(all, m) 756 return 757} 758 759// ZTestUniformString uses a z test on the given byte string, expecting all 760// bits to be uniformly set with probability 1/2. Returns non ok status if the 761// z test fails by more than 10 standard deviations. 762// 763// With less statistics jargon: This counts the number of bits set and expects 764// the number to be roughly half of the length of the string. The law of large 765// numbers suggests that we can assume that the longer the string is, the more 766// accurate that estimate becomes for a random string. This test is useful to 767// detect things like strings that are entirely zero. 768// 769// Note: By itself, this is a very weak test for randomness. 770func ZTestUniformString(bytes []byte) error { 771 expected := float64(len(bytes)) * 8.0 / 2.0 772 stddev := math.Sqrt(float64(len(bytes)) * 8.0 / 4.0) 773 numSetBits := int64(0) 774 for _, b := range bytes { 775 // Counting the number of bits set in byte: 776 for b != 0 { 777 numSetBits++ 778 b = b & (b - 1) 779 } 780 } 781 // Check that the number of bits is within 10 stddevs. 782 if math.Abs(float64(numSetBits)-expected) < 10.0*stddev { 783 return nil 784 } 785 return fmt.Errorf("Z test for uniformly distributed variable out of bounds; "+ 786 "Actual number of set bits was %d expected was %0.00f, 10 * standard deviation is 10 * %0.00f = %0.00f", 787 numSetBits, expected, stddev, 10.0*stddev) 788} 789 790func rotate(bytes []byte) []byte { 791 result := make([]byte, len(bytes)) 792 for i := 0; i < len(bytes); i++ { 793 prev := i 794 if i == 0 { 795 prev = len(bytes) 796 } 797 result[i] = (bytes[i] >> 1) | 798 (bytes[prev-1] << 7) 799 } 800 return result 801} 802 803// ZTestCrosscorrelationUniformStrings tests that the crosscorrelation of two 804// strings of equal length points to independent and uniformly distributed 805// strings. Returns non ok status if the z test fails by more than 10 standard 806// deviations. 807// 808// With less statistics jargon: This xors two strings and then performs the 809// ZTestUniformString on the result. If the two strings are independent and 810// uniformly distributed, the xor'ed string is as well. A cross correlation test 811// will find whether two strings overlap more or less than it would be expected. 812// 813// Note: Having a correlation of zero is only a necessary but not sufficient 814// condition for independence. 815func ZTestCrosscorrelationUniformStrings(bytes1, bytes2 []byte) error { 816 if len(bytes1) != len(bytes2) { 817 return fmt.Errorf( 818 "Strings are not of equal length") 819 } 820 crossed := make([]byte, len(bytes1)) 821 for i := 0; i < len(bytes1); i++ { 822 crossed[i] = bytes1[i] ^ bytes2[i] 823 } 824 return ZTestUniformString(crossed) 825} 826 827// ZTestAutocorrelationUniformString tests that the autocorrelation of a string 828// points to the bits being independent and uniformly distributed. 829// Rotates the string in a cyclic fashion. Returns non ok status if the z test 830// fails by more than 10 standard deviations. 831// 832// With less statistics jargon: This rotates the string bit by bit and performs 833// ZTestCrosscorrelationUniformStrings on each of the rotated strings and the 834// original. This will find self similarity of the input string, especially 835// periodic self similarity. For example, it is a decent test to find English 836// text (needs about 180 characters with the current settings). 837// 838// Note: Having a correlation of zero is only a necessary but not sufficient 839// condition for independence. 840func ZTestAutocorrelationUniformString(bytes []byte) error { 841 rotated := make([]byte, len(bytes)) 842 copy(rotated, bytes) 843 violations := []string{} 844 for i := 1; i < len(bytes)*8; i++ { 845 rotated = rotate(rotated) 846 err := ZTestCrosscorrelationUniformStrings(bytes, rotated) 847 if err != nil { 848 violations = append(violations, strconv.Itoa(i)) 849 } 850 } 851 if len(violations) == 0 { 852 return nil 853 } 854 return fmt.Errorf("Autocorrelation exceeded 10 standard deviation at %d indices: %s", len(violations), strings.Join(violations, ", ")) 855} 856 857// eciesAEADHKDFPublicKey returns a EciesAeadHkdfPublicKey with specified parameters. 858func eciesAEADHKDFPublicKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, x, y, salt []byte) *eciespb.EciesAeadHkdfPublicKey { 859 return &eciespb.EciesAeadHkdfPublicKey{ 860 Version: 0, 861 Params: &eciespb.EciesAeadHkdfParams{ 862 KemParams: &eciespb.EciesHkdfKemParams{ 863 CurveType: c, 864 HkdfHashType: ht, 865 HkdfSalt: salt, 866 }, 867 DemParams: &eciespb.EciesAeadDemParams{ 868 AeadDem: dekT, 869 }, 870 EcPointFormat: ptfmt, 871 }, 872 X: x, 873 Y: y, 874 } 875} 876 877// eciesAEADHKDFPrivateKey returns a EciesAeadHkdfPrivateKey with specified parameters 878func eciesAEADHKDFPrivateKey(p *eciespb.EciesAeadHkdfPublicKey, d []byte) *eciespb.EciesAeadHkdfPrivateKey { 879 return &eciespb.EciesAeadHkdfPrivateKey{ 880 Version: 0, 881 PublicKey: p, 882 KeyValue: d, 883 } 884} 885 886// GenerateECIESAEADHKDFPrivateKey generates a new EC key pair and returns the private key proto. 887func GenerateECIESAEADHKDFPrivateKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, salt []byte) (*eciespb.EciesAeadHkdfPrivateKey, error) { 888 curve, err := subtlehybrid.GetCurve(c.String()) 889 if err != nil { 890 return nil, err 891 } 892 pvt, err := subtlehybrid.GenerateECDHKeyPair(curve) 893 if err != nil { 894 return nil, err 895 } 896 pubKey := eciesAEADHKDFPublicKey(c, ht, ptfmt, dekT, pvt.PublicKey.Point.X.Bytes(), pvt.PublicKey.Point.Y.Bytes(), salt) 897 //fmt.Println(proto.MarshalTextString(pubKey)) 898 return eciesAEADHKDFPrivateKey(pubKey, pvt.D.Bytes()), nil 899} 900