Skip to content

Commit

Permalink
Create primitive from proto key serialization in XChaCha20Poly1305 ke…
Browse files Browse the repository at this point in the history
…y manager

PiperOrigin-RevId: 713959133
Change-Id: Iec0c82c3559c83a46e8114721be8b073789e14a0
  • Loading branch information
morambro authored and copybara-github committed Jan 10, 2025
1 parent 8cca13f commit 8eb3084
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 39 deletions.
27 changes: 17 additions & 10 deletions aead/xchacha20poly1305/key_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import (

"golang.org/x/crypto/chacha20poly1305"
"google.golang.org/protobuf/proto"
"github.com/tink-crypto/tink-go/v2/aead/subtle"
"github.com/tink-crypto/tink-go/v2/core/registry"
"github.com/tink-crypto/tink-go/v2/internal/protoserialization"
"github.com/tink-crypto/tink-go/v2/keyset"
"github.com/tink-crypto/tink-go/v2/subtle/random"

tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
tpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
xpb "github.com/tink-crypto/tink-go/v2/proto/xchacha20_poly1305_go_proto"
)
Expand All @@ -44,19 +45,25 @@ var _ registry.KeyManager = (*keyManager)(nil)
// Primitive constructs a XChaCha20Poly1305 for the given serialized
// [xpb.XChaCha20Poly1305Key].
func (km *keyManager) Primitive(serializedKey []byte) (any, error) {
if len(serializedKey) == 0 {
return nil, fmt.Errorf("xchacha20poly1305_key_manager: empty key")
}
key := new(xpb.XChaCha20Poly1305Key)
if err := proto.Unmarshal(serializedKey, key); err != nil {
return nil, fmt.Errorf("xchacha20poly1305_key_manager: invalid key")
keySerialization, err := protoserialization.NewKeySerialization(&tinkpb.KeyData{
TypeUrl: typeURL,
Value: serializedKey,
KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
}, tinkpb.OutputPrefixType_RAW, 0)
if err != nil {
return nil, err
}
if err := km.validateKey(key); err != nil {
key, err := protoserialization.ParseKey(keySerialization)
if err != nil {
return nil, err
}
ret, err := subtle.NewXChaCha20Poly1305(key.KeyValue)
xChaCha20Poly1305Key, ok := key.(*Key)
if !ok {
return nil, fmt.Errorf("xchacha20poly1305_key_manager: invalid key type: got %T, want %T", key, (*Key)(nil))
}
ret, err := newAEAD(xChaCha20Poly1305Key)
if err != nil {
return nil, fmt.Errorf("xchacha20poly1305_key_manager: cannot create new primitive: %v", err)
return nil, fmt.Errorf("xchacha20poly1305_key_manager: %v", err)
}
return ret, nil
}
Expand Down
61 changes: 32 additions & 29 deletions aead/xchacha20poly1305/key_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ import (
"github.com/google/go-cmp/cmp"
"golang.org/x/crypto/chacha20poly1305"
"google.golang.org/protobuf/proto"
aeadtestutil "github.com/tink-crypto/tink-go/v2/aead/internal/testutil"
"github.com/tink-crypto/tink-go/v2/core/registry"
"github.com/tink-crypto/tink-go/v2/internal/internalregistry"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"github.com/tink-crypto/tink-go/v2/testutil"
"github.com/tink-crypto/tink-go/v2/tink"

"github.com/tink-crypto/tink-go/v2/aead/subtle"
tpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
Expand Down Expand Up @@ -54,8 +56,19 @@ func TestKeyManagerGetPrimitive(t *testing.T) {
if err != nil {
t.Errorf("km.Primitive(%v) = %v; want nil", serializedKey, err)
}
if err := validateXChaCha20Poly1305Primitive(p, key); err != nil {
t.Errorf("validateXChaCha20Poly1305Primitive(p, key) = %v; want nil", err)
aead, ok := p.(tink.AEAD)
if !ok {
t.Fatalf("km.Primitive(serializedKey) = %T, want tink.AEAD", p)
}
expectedAEAD, err := subtle.NewXChaCha20Poly1305(key.GetKeyValue())
if err != nil {
t.Fatalf("subtle.NewXChaCha20Poly1305(%v) err = %v, want nil", key.GetKeyValue(), err)
}
if err := aeadtestutil.EncryptDecrypt(aead, expectedAEAD); err != nil {
t.Errorf("aeadtestutil.EncryptDecrypt(aead, expectedAEAD) = %v; want nil", err)
}
if err := aeadtestutil.EncryptDecrypt(expectedAEAD, aead); err != nil {
t.Errorf("aeadtestutil.EncryptDecrypt(expectedAEAD, aead) = %v; want nil", err)
}
}

Expand Down Expand Up @@ -139,9 +152,19 @@ func TestKeyManagerNewKeyData(t *testing.T) {
if err != nil {
t.Errorf("registry.PrimitiveFromKeyData(kd) err = %v, want nil", err)
}
_, ok := p.(*subtle.XChaCha20Poly1305)
aead, ok := p.(tink.AEAD)
if !ok {
t.Error("registry.PrimitiveFromKeyData(kd) did not return a XChaCha20Poly1305 primitive")
t.Fatalf("registry.PrimitiveFromKeyData(kd) = %T, want tink.AEAD", p)
}
expectedAEAD, err := subtle.NewXChaCha20Poly1305(key.GetKeyValue())
if err != nil {
t.Fatalf("subtle.NewXChaCha20Poly1305(%v) err = %v, want nil", key.GetKeyValue(), err)
}
if err := aeadtestutil.EncryptDecrypt(aead, expectedAEAD); err != nil {
t.Errorf("aeadtestutil.EncryptDecrypt(aead, expectedAEAD) = %v; want nil", err)
}
if err := aeadtestutil.EncryptDecrypt(expectedAEAD, aead); err != nil {
t.Errorf("aeadtestutil.EncryptDecrypt(expectedAEAD, aead) = %v; want nil", err)
}
}

Expand Down Expand Up @@ -301,38 +324,18 @@ func TestKeyManagerDeriveKeyFailsWithInsufficientRandomness(t *testing.T) {
}
}

func validateXChaCha20Poly1305Primitive(p any, key *xpb.XChaCha20Poly1305Key) error {
cipher := p.(*subtle.XChaCha20Poly1305)

// Try to encrypt and decrypt.
pt := random.GetRandomBytes(32)
aad := random.GetRandomBytes(32)
ct, err := cipher.Encrypt(pt, aad)
if err != nil {
return fmt.Errorf("encryption failed")
}
decrypted, err := cipher.Decrypt(ct, aad)
if err != nil {
return fmt.Errorf("decryption failed")
}
if !bytes.Equal(decrypted, pt) {
return fmt.Errorf("decryption failed")
}
return nil
}

func validateXChaCha20Poly1305Key(key *xpb.XChaCha20Poly1305Key) error {
if key.Version != testutil.XChaCha20Poly1305KeyVersion {
if key.GetVersion() != testutil.XChaCha20Poly1305KeyVersion {
return fmt.Errorf("incorrect key version: keyVersion != %d", testutil.XChaCha20Poly1305KeyVersion)
}
if uint32(len(key.KeyValue)) != chacha20poly1305.KeySize {
if uint32(len(key.GetKeyValue())) != chacha20poly1305.KeySize {
return fmt.Errorf("incorrect key size: keySize != %d", chacha20poly1305.KeySize)
}

// Try to encrypt and decrypt.
p, err := subtle.NewXChaCha20Poly1305(key.KeyValue)
p, err := subtle.NewXChaCha20Poly1305(key.GetKeyValue())
if err != nil {
return fmt.Errorf("invalid key: %v", key.KeyValue)
return fmt.Errorf("invalid key: %v", key.GetKeyValue())
}
return validateXChaCha20Poly1305Primitive(p, key)
return aeadtestutil.EncryptDecrypt(p, p)
}

0 comments on commit 8eb3084

Please sign in to comment.