diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh.go index 0273d1ba5c..3fd90d3f58 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh.go @@ -112,4 +112,14 @@ func init() { if err != nil { panic(fmt.Sprintf("ecdh.init() failed: %v", err)) } + + err = registry.RegisterKeyManager(newECDHXChachaPublicKeyManager()) + if err != nil { + panic(fmt.Sprintf("ecdh.init() failed: %v", err)) + } + + err = registry.RegisterKeyManager(newECDHXChachaPrivateKeyManager()) + if err != nil { + panic(fmt.Sprintf("ecdh.init() failed: %v", err)) + } } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_private_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_private_key_manager_test.go index e927d4782b..ae78a12a1e 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_private_key_manager_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_private_key_manager_test.go @@ -130,7 +130,7 @@ func TestECDHESPrivateKeyManager_Primitive(t *testing.T) { c = tt.curveType } - pubKeyProto := &ecdhpb.EcdhAeadPrivateKey{ + privKeyProto := &ecdhpb.EcdhAeadPrivateKey{ Version: v, PublicKey: &ecdhpb.EcdhAeadPublicKey{ Version: v, // if v > 0 to force an error when calling km.Primitive() @@ -149,10 +149,10 @@ func TestECDHESPrivateKeyManager_Primitive(t *testing.T) { KeyValue: d, } - sPubKey, err := proto.Marshal(pubKeyProto) + sPrivKey, err := proto.Marshal(privKeyProto) require.NoError(t, err) - p, err := km.Primitive(sPubKey) + p, err := km.Primitive(sPrivKey) if bytes.Equal(tt.encTmp.Value, badSerializedFormat) { require.EqualError(t, err, errInvalidECDHAESPrivateKey.Error(), "ECDHESPrivate primitive from serialized key with invalid serialized key") @@ -259,12 +259,12 @@ func TestEcdhesPrivateKeyManager_NewKey(t *testing.T) { privKeyProto := &ecdhpb.EcdhAeadKeyFormat{ Params: &ecdhpb.EcdhAeadParams{ KwParams: &ecdhpb.EcdhKwParams{ - CurveType: c, // unknown curve type to force an error when calling km.Primitive() + CurveType: c, // unknown curve type to force an error when calling km.NewKey() }, EncParams: &ecdhpb.EcdhAeadEncParams{ - AeadEnc: encT, // invalid data enc key template to force an error when calling km.Primitive() + AeadEnc: encT, // invalid data enc key template to force an error when calling km.NewKey() }, - EcPointFormat: ptFmt, // unknown EC Point format type to force an error when calling km.Primitive() + EcPointFormat: ptFmt, // unknown EC Point format type to force an error when calling km.NewKey() }, } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_public_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_public_key_manager.go index 439d4c0548..055487ebf2 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_public_key_manager.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_aes_aead_public_key_manager.go @@ -92,7 +92,7 @@ func (km *ecdhPublicKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb. func (km *ecdhPublicKeyManager) validateKey(key *ecdhpb.EcdhAeadPublicKey) (elliptic.Curve, error) { err := keyset.ValidateKeyVersion(key.Version, ecdhAESPublicKeyVersion) if err != nil { - return nil, fmt.Errorf("ecdh_aes_publie_key_manager: invalid key: %w", err) + return nil, fmt.Errorf("ecdh_aes_public_key_manager: invalid key: %w", err) } return validateKeyFormat(key.Params) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_factory_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_factory_test.go index 416e82828a..48a7ed3d18 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_factory_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_factory_test.go @@ -122,8 +122,8 @@ func ecdhAEADPublicKey(t *testing.T, c commonpb.EllipticCurveType, ptfmt commonp } } -// eciesAEADESPrivateKey returns a EciesAeadHkdfPrivateKey with specified parameters. -func eciesAEADESPrivateKey(t *testing.T, p *ecdhpb.EcdhAeadPublicKey, d []byte) *ecdhpb.EcdhAeadPrivateKey { +// ecdhesAEADPrivateKey returns a EcdhAeadPrivateKey with specified parameters. +func ecdhesAEADPrivateKey(t *testing.T, p *ecdhpb.EcdhAeadPublicKey, d []byte) *ecdhpb.EcdhAeadPrivateKey { t.Helper() return &ecdhpb.EcdhAeadPrivateKey{ @@ -146,7 +146,7 @@ func generateECDHAEADPrivateKey(t *testing.T, c commonpb.EllipticCurveType, ptfm pubKey := ecdhAEADPublicKey(t, c, ptfmt, encT, pvt.PublicKey.Point.X.Bytes(), pvt.PublicKey.Point.Y.Bytes(), cek) - return eciesAEADESPrivateKey(t, pubKey, pvt.D.Bytes()) + return ecdhesAEADPrivateKey(t, pubKey, pvt.D.Bytes()) } func TestECDHESFactoryWithBadKeysetType(t *testing.T) { diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template.go index 1eb6af08b4..33e56aa825 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template.go @@ -45,10 +45,19 @@ func ECDH521KWAES256GCMKeyTemplate() *tinkpb.KeyTemplate { return createKeyTemplate(commonpb.EllipticCurveType_NIST_P521, nil) } +// XChachaECDHKeyTemplate is a KeyTemplate that generates a key that accepts a CEK for XChacha20Poly1305 encryption. CEK +// wrapping is done outside of this Tink key (in the tinkcrypto service). It is used to represent a key to execute the +// CompositeDecrypt primitive with the following parameters: +// - Content Encryption: XChaha20Poly1305 +// Keys from this template represent a valid recipient public/private key pairs and can be stored in the kms. +func XChachaECDHKeyTemplate() *tinkpb.KeyTemplate { + return createXChachaKeyTemplate(nil) +} + // AES256GCMKeyTemplateWithCEK is similar to ECDHAES256GCMKeyTemplate but adding the cek to execute the // CompositeEncrypt primitive for encrypting a message targeted to one ore more recipients. // Keys from this template offer valid CompositeEncrypt primitive execution only and should not be stored in the KMS. -// The key created from this template has no recipient key info linked to it. It is use exclusively used for primitive +// The key created from this template has no recipient key info linked to it. It is exclusively used for primitive // execution. func AES256GCMKeyTemplateWithCEK(cek []byte) *tinkpb.KeyTemplate { // the curve passed in the template below is ignored when executing the primitive, it's hardcoded to pass key @@ -56,7 +65,41 @@ func AES256GCMKeyTemplateWithCEK(cek []byte) *tinkpb.KeyTemplate { return createKeyTemplate(0, cek) } -// TODO add chacha key templates as well https://github.com/hyperledger/aries-framework-go/issues/1637 +// XChachaKeyTemplateWithCEK is similar to XChachaKeyTemplate but adding the cek to execute the +// CompositeEncrypt primitive for encrypting a message targeted to one ore more recipients. +// Keys from this template offer valid CompositeEncrypt primitive execution only and should not be stored in the KMS. +// The key created from this template has no recipient key info linked to it. It is exclusively used for primitive +// execution. +func XChachaKeyTemplateWithCEK(cek []byte) *tinkpb.KeyTemplate { + return createXChachaKeyTemplate(cek) +} + +// createXChachaKeyTemplate creates a new ECDH-AEAD key template with the set cek for primitive execution. +func createXChachaKeyTemplate(cek []byte) *tinkpb.KeyTemplate { + format := &ecdhpb.EcdhAeadKeyFormat{ + Params: &ecdhpb.EcdhAeadParams{ + KwParams: &ecdhpb.EcdhKwParams{ + KeyType: ecdhpb.KeyType_OKP, + }, + EncParams: &ecdhpb.EcdhAeadEncParams{ + AeadEnc: aead.XChaCha20Poly1305KeyTemplate(), + CEK: cek, + }, + EcPointFormat: commonpb.EcPointFormat_UNCOMPRESSED, + }, + } + + serializedFormat, err := proto.Marshal(format) + if err != nil { + panic("failed to marshal EcdhAeadKeyFormat proto for XChacha key") + } + + return &tinkpb.KeyTemplate{ + TypeUrl: ecdhXChachaPrivateKeyTypeURL, + Value: serializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + } +} // createKeyTemplate creates a new ECDH-AEAD key template with the set cek for primitive execution. func createKeyTemplate(c commonpb.EllipticCurveType, cek []byte) *tinkpb.KeyTemplate { diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template_test.go index 0782007124..3cee90825d 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_key_template_test.go @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package ecdh import ( + "strings" "testing" "github.com/google/tink/go/keyset" @@ -36,6 +37,10 @@ func TestECDHESKeyTemplateSuccess(t *testing.T) { curveType: "P-521", tmplFunc: ECDH521KWAES256GCMKeyTemplate, }, + { + tcName: "creat ECDH XChacha key templates test", + tmplFunc: XChachaECDHKeyTemplate, + }, } for _, tt := range flagTests { @@ -63,7 +68,11 @@ func TestECDHESKeyTemplateSuccess(t *testing.T) { require.Empty(t, ct) // now try to create a new KH for primitive execution and try to encrypt - kt = AES256GCMKeyTemplateWithCEK(cek) + if strings.Contains(tc.tcName, "XChacha") { + kt = XChachaKeyTemplateWithCEK(cek) + } else { + kt = AES256GCMKeyTemplateWithCEK(cek) + } kh, err = keyset.NewHandle(kt) require.NoError(t, err) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_x25519_private_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_x25519_private_key_manager.go deleted file mode 100644 index beb29793d7..0000000000 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_x25519_private_key_manager.go +++ /dev/null @@ -1,9 +0,0 @@ -/* -Copyright SecureKey Technologies Inc. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package ecdh - -// TODO implement diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager.go new file mode 100644 index 0000000000..69590e36ad --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager.go @@ -0,0 +1,200 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh + +import ( + "crypto/ed25519" + "crypto/rand" + "errors" + "fmt" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/core/registry" + "github.com/google/tink/go/keyset" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh/subtle" + ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil" +) + +const ( + ecdhXChachaPrivateKeyVersion = 0 + ecdhXChachaPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPrivateKey" +) + +// common errors. +var ( + errInvalidECDHXChachaPrivateKey = errors.New("ecdh_xchacha_private_key_manager: invalid key") + errInvalidECDHXChachaPrivateKeyFormat = errors.New("ecdh_xchacha_private_key_manager: invalid key format") +) + +// ecdhXChachaPrivateKeyManager is an implementation of PrivateKeyManager interface. +// It generates new ECDHPrivateKey (XChacha) keys and produces new instances of ECDHAEADCompositeDecrypt subtle. +type ecdhXChachaPrivateKeyManager struct{} + +// Assert that ecdhXChachaPrivateKeyManager implements the PrivateKeyManager interface. +var _ registry.PrivateKeyManager = (*ecdhXChachaPrivateKeyManager)(nil) + +// newECDHXChachaPrivateKeyManager creates a new ecdhXChachaPrivateKeyManager. +func newECDHXChachaPrivateKeyManager() *ecdhXChachaPrivateKeyManager { + return new(ecdhXChachaPrivateKeyManager) +} + +// Primitive creates an ECDHESPrivateKey subtle for the given serialized ECDHESPrivateKey proto. +func (km *ecdhXChachaPrivateKeyManager) Primitive(serializedKey []byte) (interface{}, error) { + if len(serializedKey) == 0 { + return nil, errInvalidECDHXChachaPrivateKey + } + + key := new(ecdhpb.EcdhAeadPrivateKey) + + err := proto.Unmarshal(serializedKey, key) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKey + } + + err = km.validateKey(key) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKey + } + + rEnc, err := composite.NewRegisterCompositeAEADEncHelper(key.PublicKey.Params.EncParams.AeadEnc) + if err != nil { + return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: NewRegisterCompositeAEADEncHelper "+ + "failed: %w", err) + } + + return subtle.NewECDHAEADCompositeDecrypt(rEnc, key.PublicKey.Params.EncParams.CEK), nil +} + +// NewKey creates a new key according to the specification of ECDHESPrivateKey format. +func (km *ecdhXChachaPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { + if len(serializedKeyFormat) == 0 { + return nil, errInvalidECDHXChachaPrivateKeyFormat + } + + keyFormat := new(ecdhpb.EcdhAeadKeyFormat) + + err := proto.Unmarshal(serializedKeyFormat, keyFormat) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKeyFormat + } + + err = validateKeyXChachaFormat(keyFormat.Params) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKeyFormat + } + + pub, pvt, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: GenerateECDHKeyPair failed: %w", err) + } + + x25519Pub, err := cryptoutil.PublicEd25519toCurve25519(pub) + if err != nil { + return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: Convert to X25519 pub key failed: %w", err) + } + + x25519Pvt, err := cryptoutil.SecretEd25519toCurve25519(pvt) + if err != nil { + return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: Convert to X25519 priv key failed: %w", err) + } + + return &ecdhpb.EcdhXChachaAeadPrivateKey{ + Version: ecdhXChachaPrivateKeyVersion, + KeyValue: x25519Pvt, + PublicKey: &ecdhpb.EcdhXChachaAeadPublicKey{ + Version: ecdhXChachaPrivateKeyVersion, + Params: keyFormat.Params, + KeyValue: x25519Pub, + }, + }, nil +} + +// NewKeyData creates a new KeyData according to the specification of ECDHESPrivateKey Format. +// It should be used solely by the key management API. +func (km *ecdhXChachaPrivateKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { + key, err := km.NewKey(serializedKeyFormat) + if err != nil { + return nil, err + } + + serializedKey, err := proto.Marshal(key) + if err != nil { + return nil, fmt.Errorf("ecdhes_xchacha_private_key_manager: Proto.Marshal failed: %w", err) + } + + return &tinkpb.KeyData{ + TypeUrl: ecdhXChachaPrivateKeyTypeURL, + Value: serializedKey, + KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, + }, nil +} + +// PublicKeyData returns the enclosed public key data of serializedPrivKey. +func (km *ecdhXChachaPrivateKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { + privKey := new(ecdhpb.EcdhAeadPrivateKey) + + err := proto.Unmarshal(serializedPrivKey, privKey) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKey + } + + serializedPubKey, err := proto.Marshal(privKey.PublicKey) + if err != nil { + return nil, errInvalidECDHXChachaPrivateKey + } + + return &tinkpb.KeyData{ + TypeUrl: ecdhXChachaPublicKeyTypeURL, + Value: serializedPubKey, + KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC, + }, nil +} + +// DoesSupport indicates if this key manager supports the given key type. +func (km *ecdhXChachaPrivateKeyManager) DoesSupport(typeURL string) bool { + return typeURL == ecdhXChachaPrivateKeyTypeURL +} + +// TypeURL returns the key type of keys managed by this key manager. +func (km *ecdhXChachaPrivateKeyManager) TypeURL() string { + return ecdhXChachaPrivateKeyTypeURL +} + +// validateKey validates the given ECDHPrivateKey and returns the KW curve. +func (km *ecdhXChachaPrivateKeyManager) validateKey(key *ecdhpb.EcdhAeadPrivateKey) error { + err := keyset.ValidateKeyVersion(key.Version, ecdhXChachaPrivateKeyVersion) + if err != nil { + return fmt.Errorf("ecdhes_xchacha_private_key_manager: invalid key: %w", err) + } + + return validateKeyXChachaFormat(key.PublicKey.Params) +} + +// validateKeyFormat validates the given ECDHESKeyFormat and returns the KW Curve. +func validateKeyXChachaFormat(params *ecdhpb.EcdhAeadParams) error { + var err error + + km, err := registry.GetKeyManager(params.EncParams.AeadEnc.TypeUrl) + if err != nil { + return fmt.Errorf("ecdhes_aes_private_key_manager: GetKeyManager error: %w", err) + } + + _, err = km.NewKeyData(params.EncParams.AeadEnc.Value) + if err != nil { + return fmt.Errorf("ecdhes_aes_private_key_manager: NewKeyData error: %w", err) + } + + if params.KwParams.KeyType.String() != ecdhpb.KeyType_OKP.String() { + return fmt.Errorf("ecdhes_aes_private_key_manager: invalid key type %v", params.KwParams.KeyType) + } + + return nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager_test.go new file mode 100644 index 0000000000..8322640484 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager_test.go @@ -0,0 +1,214 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh + +import ( + "crypto/ed25519" + "crypto/rand" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/aead" + commonpb "github.com/google/tink/go/proto/common_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/stretchr/testify/require" + + ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil" +) + +func TestECDHESXChachaPrivateKeyManager_Primitive(t *testing.T) { + km := newECDHXChachaPrivateKeyManager() + + t.Run("Test private key manager Primitive() with empty serialized key", func(t *testing.T) { + p, err := km.Primitive([]byte("")) + require.EqualError(t, err, errInvalidECDHXChachaPrivateKey.Error(), + "ECDHESPrivate primitive from empty serialized key must fail") + require.Empty(t, p) + }) + + t.Run("Test private key manager Primitive() with bad serialize key", func(t *testing.T) { + p, err := km.Primitive([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDHXChachaPrivateKey.Error(), + "ECDHESPrivate primitive from bad serialized key must fail") + require.Empty(t, p) + }) + + flagTests := []struct { + tcName string + version uint32 + encTmp *tinkpb.KeyTemplate + }{ + { + tcName: "private key manager Primitive() using key with bad version", + version: 9999, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "success private key manager Primitive()", + version: 0, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "private key manager Primitive() using key with bad key template URL", + version: 0, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + pub, pvt, err := ed25519.GenerateKey(rand.Reader) + require.NoError(t, err) + + x25519Pub, err := cryptoutil.PublicEd25519toCurve25519(pub) + require.NoError(t, err) + + x25519Pvt, err := cryptoutil.SecretEd25519toCurve25519(pvt) + require.NoError(t, err) + + params := &ecdhpb.EcdhAeadParams{ + KwParams: &ecdhpb.EcdhKwParams{ + KeyType: ecdhpb.KeyType_OKP, + }, + EncParams: &ecdhpb.EcdhAeadEncParams{ + AeadEnc: tt.encTmp, + CEK: []byte{}, + }, + EcPointFormat: commonpb.EcPointFormat_UNCOMPRESSED, + } + + privKeyProto := &ecdhpb.EcdhXChachaAeadPrivateKey{ + Version: tt.version, + KeyValue: x25519Pvt, + PublicKey: &ecdhpb.EcdhXChachaAeadPublicKey{ + Version: ecdhXChachaPrivateKeyVersion, + Params: params, + KeyValue: x25519Pub, + }, + } + + sPrivKey, err := proto.Marshal(privKeyProto) + require.NoError(t, err) + + p, err := km.Primitive(sPrivKey) + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} + +func TestEcdhesXChachaPrivateKeyManager_DoesSupport(t *testing.T) { + km := newECDHXChachaPrivateKeyManager() + require.False(t, km.DoesSupport("bad/url")) + require.True(t, km.DoesSupport(ecdhXChachaPrivateKeyTypeURL)) +} + +func TestEcdhesXChachaPrivateKeyManager_NewKey(t *testing.T) { + km := newECDHXChachaPrivateKeyManager() + + t.Run("Test private key manager NewKey() with nil key", func(t *testing.T) { + k, err := km.NewKey(nil) + require.EqualError(t, err, errInvalidECDHXChachaPrivateKeyFormat.Error()) + require.Empty(t, k) + }) + + t.Run("Test private key manager NewKey() with bad serialize key", func(t *testing.T) { + p, err := km.NewKey([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDHXChachaPrivateKeyFormat.Error(), + "ECDHESPrivate NewKey() from bad serialized key must fail") + require.Empty(t, p) + }) + + flagTests := []struct { + tcName string + keyType ecdhpb.KeyType + encTmp *tinkpb.KeyTemplate + }{ + { + tcName: "success private key manager NewKey() and NewKeyData()", + keyType: ecdhpb.KeyType_OKP, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "private key manager NewKey() and NewKeyData() using key with bad key type", + keyType: ecdhpb.KeyType_EC, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "private key manager NewKey() and NewKeyData() using key with bad key template URL", + keyType: ecdhpb.KeyType_OKP, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + privKeyProto := &ecdhpb.EcdhAeadKeyFormat{ + Params: &ecdhpb.EcdhAeadParams{ + KwParams: &ecdhpb.EcdhKwParams{ + KeyType: tt.keyType, // unknown curve type to force an error when calling km.NewKey() + }, + EncParams: &ecdhpb.EcdhAeadEncParams{ + AeadEnc: tt.encTmp, // invalid data enc key template to force an error when calling km.NewKey() + }, + EcPointFormat: commonpb.EcPointFormat_UNCOMPRESSED, + }, + } + + sPrivKey, err := proto.Marshal(privKeyProto) + require.NoError(t, err) + + p, err := km.NewKey(sPrivKey) + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + + sp, e := proto.Marshal(p) + require.NoError(t, e) + require.NotEmpty(t, sp) + + // try PublicKeyData() with bad serialized private key + pubK, e := km.PublicKeyData([]byte("bad serialized private key")) + require.Error(t, e) + require.Empty(t, pubK) + + // try PublicKeyData() with valid serialized private key + pubK, e = km.PublicKeyData(sp) + require.NoError(t, e) + require.NotEmpty(t, pubK) + } + + kd, err := km.NewKeyData(sPrivKey) + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, kd) + require.Equal(t, kd.TypeUrl, ecdhXChachaPrivateKeyTypeURL) + require.Equal(t, kd.KeyMaterialType, tinkpb.KeyData_ASYMMETRIC_PRIVATE) + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager.go new file mode 100644 index 0000000000..d2ca40dad9 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager.go @@ -0,0 +1,98 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh + +import ( + "errors" + "fmt" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/core/registry" + "github.com/google/tink/go/keyset" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh/subtle" + ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" +) + +const ( + ecdhXChachaPublicKeyVersion = 0 + ecdhXChachaPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPublicKey" +) + +// common errors. +var errInvalidECDHXChachaPublicKey = errors.New("ecdh_xchacha_public_key_manager: invalid key") + +// ecdhXChachaPublicKeyManager is an implementation of KeyManager interface. +// It generates new ECDHPublicKey (XChacha) keys and produces new instances of ECDHAEADCompositeEncrypt subtle. +type ecdhXChachaPublicKeyManager struct{} + +// Assert that ecdhXChachaPublicKeyManager implements the KeyManager interface. +var _ registry.KeyManager = (*ecdhXChachaPublicKeyManager)(nil) + +// newECDHXChachaPublicKeyManager creates a new ecdhXChachaPublicKeyManager. +func newECDHXChachaPublicKeyManager() *ecdhXChachaPublicKeyManager { + return new(ecdhXChachaPublicKeyManager) +} + +// Primitive creates an ECDHESXChachaPublicKey subtle for the given serialized ECDHESXChachaPublicKey proto. +func (km *ecdhXChachaPublicKeyManager) Primitive(serializedKey []byte) (interface{}, error) { + if len(serializedKey) == 0 { + return nil, errInvalidECDHXChachaPublicKey + } + + ecdhPubKey := new(ecdhpb.EcdhAeadPublicKey) + + err := proto.Unmarshal(serializedKey, ecdhPubKey) + if err != nil { + return nil, errInvalidECDHXChachaPublicKey + } + + err = km.validateKey(ecdhPubKey) + if err != nil { + return nil, errInvalidECDHXChachaPublicKey + } + + rEnc, err := composite.NewRegisterCompositeAEADEncHelper(ecdhPubKey.Params.EncParams.AeadEnc) + if err != nil { + return nil, fmt.Errorf("ecdh_xchacha_public_key_manager: NewRegisterCompositeAEADEncHelper "+ + "failed: %w", err) + } + + return subtle.NewECDHAEADCompositeEncrypt(rEnc, ecdhPubKey.Params.EncParams.CEK), nil +} + +// DoesSupport indicates if this key manager supports the given key type. +func (km *ecdhXChachaPublicKeyManager) DoesSupport(typeURL string) bool { + return typeURL == ecdhXChachaPublicKeyTypeURL +} + +// TypeURL returns the key type of keys managed by this key manager. +func (km *ecdhXChachaPublicKeyManager) TypeURL() string { + return ecdhXChachaPublicKeyTypeURL +} + +// NewKey is not implemented for public key manager. +func (km *ecdhXChachaPublicKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { + return nil, errors.New("ecdh_xchacha_public_key_manager: NewKey not implemented") +} + +// NewKeyData is not implemented for public key manager. +func (km *ecdhXChachaPublicKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { + return nil, errors.New("ecdh_xchacha_public_key_manager: NewKeyData not implemented") +} + +// validateKey validates the given ECDHESPublicKey. +func (km *ecdhXChachaPublicKeyManager) validateKey(key *ecdhpb.EcdhAeadPublicKey) error { + err := keyset.ValidateKeyVersion(key.Version, ecdhXChachaPublicKeyVersion) + if err != nil { + return fmt.Errorf("ecdh_xchacha_public_key_manager: invalid key: %w", err) + } + + return validateKeyXChachaFormat(key.Params) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager_test.go new file mode 100644 index 0000000000..33c89133da --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_public_key_manager_test.go @@ -0,0 +1,145 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh + +import ( + "crypto/ed25519" + "crypto/rand" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/aead" + commonpb "github.com/google/tink/go/proto/common_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/stretchr/testify/require" + + ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil" +) + +func TestECDHXChachaPublicKeyManager_Primitive(t *testing.T) { + km := newECDHXChachaPublicKeyManager() + + t.Run("Test public key manager Primitive() with empty serialized key", func(t *testing.T) { + p, err := km.Primitive([]byte("")) + require.EqualError(t, err, errInvalidECDHXChachaPublicKey.Error(), + "ECDHPublic primitive from empty serialized key must fail") + require.Empty(t, p) + }) + + t.Run("Test public key manager Primitive() with bad serialize key", func(t *testing.T) { + p, err := km.Primitive([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDHXChachaPublicKey.Error(), + "ECDHPublic primitive from bad serialized key must fail") + require.Empty(t, p) + }) + + flagTests := []struct { + tcName string + version uint32 + keyType ecdhpb.KeyType + encTmp *tinkpb.KeyTemplate + }{ + { + tcName: "public key manager Primitive() using key with bad version", + version: 9999, + keyType: ecdhpb.KeyType_OKP, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "public key manager Primitive() using key with bad key type", + version: 0, + keyType: ecdhpb.KeyType_EC, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "success public key manager Primitive()", + version: 0, + keyType: ecdhpb.KeyType_OKP, + encTmp: aead.XChaCha20Poly1305KeyTemplate(), + }, + { + tcName: "public key manager Primitive() using key with bad key template URL", + version: 0, + keyType: ecdhpb.KeyType_OKP, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + pub, _, err := ed25519.GenerateKey(rand.Reader) + require.NoError(t, err) + + x25519Pub, err := cryptoutil.PublicEd25519toCurve25519(pub) + require.NoError(t, err) + + pubKeyProto := &ecdhpb.EcdhXChachaAeadPublicKey{ + Version: tt.version, // if version > 0 to force an error when calling km.Primitive() + Params: &ecdhpb.EcdhAeadParams{ + KwParams: &ecdhpb.EcdhKwParams{ + KeyType: tt.keyType, // invalid key type to force error when calling km.Primitive() + }, + EncParams: &ecdhpb.EcdhAeadEncParams{ + AeadEnc: tt.encTmp, // invalid data enc key template to force error when calling km.Primitive() + CEK: []byte{}, + }, + EcPointFormat: commonpb.EcPointFormat_UNCOMPRESSED, + }, + KeyValue: x25519Pub, + } + + sPubKey, err := proto.Marshal(pubKeyProto) + require.NoError(t, err) + + p, err := km.Primitive(sPubKey) + if strings.Contains(tt.tcName, "with bad content encryption key size") { + require.EqualError(t, err, errInvalidECDHXChachaPublicKey.Error(), + "ECDHPublic primitive from serialized key with invalid serialized key") + require.Empty(t, p) + + return + } + + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} + +func TestEcdhXChachaPublicKeyManager_DoesSupport(t *testing.T) { + km := newECDHXChachaPublicKeyManager() + require.False(t, km.DoesSupport("bad/url")) + require.True(t, km.DoesSupport(ecdhXChachaPublicKeyTypeURL)) +} + +func TestEcdhXChachaPublicKeyManager_NewKeyAndNewKeyData(t *testing.T) { + km := newECDHXChachaPublicKeyManager() + + t.Run("Test public key manager NewKey()", func(t *testing.T) { + k, err := km.NewKey(nil) + require.EqualError(t, err, "ecdh_xchacha_public_key_manager: NewKey not implemented") + require.Empty(t, k) + }) + + t.Run("Test private key manager NewKeyData()", func(t *testing.T) { + p, err := km.NewKeyData(nil) + require.EqualError(t, err, "ecdh_xchacha_public_key_manager: NewKeyData not implemented") + require.Empty(t, p) + }) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go index 5cf63c3832..615115f29d 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go @@ -30,12 +30,14 @@ import ( // key (aka PublicKeyToHandle to be used as a valid Tink key) const ( - ecdhAESPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAesAeadPublicKey" + ecdhAESPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAesAeadPublicKey" + ecdhXChachaPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPublicKey" ) // PubKeyWriter will write the raw bytes of a Tink KeySet's primary public key. The raw bytes are a marshaled // composite.VerificationMethod type. -// The keyset must have a keyURL value equal to `ecdhAESPublicKeyTypeURL` constant of ecdh package. +// The keyset must have a keyURL value equal to `ecdhAESPublicKeyTypeURL` or `ecdhXChachaPublicKeyTypeURL` constant of +// ecdh package. // Note: This writer should be used only for ECDH public key exports. Other export of public keys should be // called via localkms package. type PubKeyWriter struct { @@ -115,6 +117,11 @@ func protoToCompositeKey(keyData *tinkpb.KeyData) (*cryptoapi.PublicKey, error) if err != nil { return nil, err } + case ecdhXChachaPublicKeyTypeURL: + cKey, err = newECDHXChachaKey(keyData.Value) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("can't export key with keyURL:%s", keyData.TypeUrl) } @@ -123,6 +130,7 @@ func protoToCompositeKey(keyData *tinkpb.KeyData) (*cryptoapi.PublicKey, error) } func buildKey(c compositeKeyGetter) (*cryptoapi.PublicKey, error) { + // TODO build XChacha key differently curveName := c.curveName() keyTypeName := c.keyType() @@ -246,7 +254,7 @@ func PublicKeyToKeysetHandle(pubKey *cryptoapi.PublicKey) (*keyset.Handle, error Params: &ecdhpb.EcdhAeadParams{ KwParams: &ecdhpb.EcdhKwParams{ CurveType: cp, - KeyType: ecdhpb.KeyType_EC, // for now, TODO create getTypeProto(pubKey.Type) function + KeyType: ecdhpb.KeyType_EC, }, EncParams: &ecdhpb.EcdhAeadEncParams{ AeadEnc: aead.AES256GCMKeyTemplate(), @@ -308,3 +316,8 @@ func newKeySet(tURL string, marshalledKey []byte, keyMaterialType tinkpb.KeyData PrimaryKeyId: 1, } } + +func newECDHXChachaKey(mKey []byte) (compositeKeyGetter, error) { + // TODO implement + return nil, nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go index d54a61ce13..b286de0f59 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go @@ -30,7 +30,7 @@ func TestPubKeyExport(t *testing.T) { keyTemplate *tinkpb.KeyTemplate }{ { - tcName: "export then read AES256GCM with ECDH P-256 public recipient key", + tcName: "export then read AES256GCM with ECDHES P-256 public recipient key", keyTemplate: ecdh.ECDH256KWAES256GCMKeyTemplate(), }, { diff --git a/pkg/crypto/tinkcrypto/primitive/composite/register_ecdh_aead_enc_helper.go b/pkg/crypto/tinkcrypto/primitive/composite/register_ecdh_aead_enc_helper.go index 0d1b3b6a35..bf5f24c560 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/register_ecdh_aead_enc_helper.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/register_ecdh_aead_enc_helper.go @@ -66,25 +66,71 @@ func NewRegisterCompositeAEADEncHelper(k *tinkpb.KeyTemplate) (*RegisterComposit skf, err = proto.Marshal(gcmKeyFormat) if err != nil { - return nil, fmt.Errorf("compositeAEADEncHelper: failed to serialize key format, error: %w", err) + return nil, fmt.Errorf("compositeAEADEncHelper: failed to serialize gcm key format, error: %w", err) } case ChaCha20Poly1305TypeURL: tagSize = poly1305.TagSize ivSize = chacha20poly1305.NonceSize + + skf, err = buildChachaSDF(k) + if err != nil { + return nil, err + } case XChaCha20Poly1305TypeURL: tagSize = poly1305.TagSize ivSize = chacha20poly1305.NonceSizeX + + skf, err = buildXChachaSKF(k) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("compositeAEADEncHelper: unsupported AEAD content encryption key type: %s", k.TypeUrl) } + return buildRegisterCompositeAEADEncHelper(k, skf, tagSize, ivSize) +} + +func buildChachaSDF(k *tinkpb.KeyTemplate) ([]byte, error) { + chachaKeyFormat := new(chachapb.ChaCha20Poly1305KeyFormat) + + err := proto.Unmarshal(k.Value, chachaKeyFormat) + if err != nil { + return nil, fmt.Errorf("compositeAEADEncHelper: failed to unmarshal chachaKeyFormat: %w", err) + } + + skf, err := proto.Marshal(chachaKeyFormat) + if err != nil { + return nil, fmt.Errorf("compositeAEADEncHelper: failed to serialize chacha key format, error: %w", err) + } + + return skf, nil +} + +func buildXChachaSKF(k *tinkpb.KeyTemplate) ([]byte, error) { + xChachaKeyFormat := new(xchachapb.XChaCha20Poly1305KeyFormat) + + err := proto.Unmarshal(k.Value, xChachaKeyFormat) + if err != nil { + return nil, fmt.Errorf("compositeAEADEncHelper: failed to unmarshal xChachaKeyFormat: %w", err) + } + + skf, err := proto.Marshal(xChachaKeyFormat) + if err != nil { + return nil, fmt.Errorf("compositeAEADEncHelper: failed to serialize xChacha key format, error: %w", err) + } + + return skf, nil +} + +func buildRegisterCompositeAEADEncHelper(k *tinkpb.KeyTemplate, skf []byte, + tagSize, ivSize int) (*RegisterCompositeAEADEncHelper, error) { km, err := registry.GetKeyManager(k.TypeUrl) if err != nil { return nil, fmt.Errorf("compositeAEADEncHelper: failed to fetch KeyManager, error: %w", err) } - // skf is nil for (X)Chahcha20Poly1305 km key, err := km.NewKey(skf) if err != nil { return nil, fmt.Errorf("compositeAEADEncHelper: failed to fetch key, error: %w", err) diff --git a/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto/ecdh_aead.pb.go b/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto/ecdh_aead.pb.go index 0f24ed39a2..7fc08188f9 100755 --- a/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto/ecdh_aead.pb.go +++ b/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto/ecdh_aead.pb.go @@ -364,6 +364,124 @@ func (m *EcdhAeadKeyFormat) GetParams() *EcdhAeadParams { return nil } +type EcdhXChachaAeadPublicKey struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Params *EcdhAeadParams `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` + KID string `protobuf:"bytes,3,opt,name=KID,proto3" json:"KID,omitempty"` + KeyValue []byte `protobuf:"bytes,4,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EcdhXChachaAeadPublicKey) Reset() { *m = EcdhXChachaAeadPublicKey{} } +func (m *EcdhXChachaAeadPublicKey) String() string { return proto.CompactTextString(m) } +func (*EcdhXChachaAeadPublicKey) ProtoMessage() {} +func (*EcdhXChachaAeadPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_62f9291a7083da43, []int{6} +} + +func (m *EcdhXChachaAeadPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EcdhXChachaAeadPublicKey.Unmarshal(m, b) +} +func (m *EcdhXChachaAeadPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EcdhXChachaAeadPublicKey.Marshal(b, m, deterministic) +} +func (m *EcdhXChachaAeadPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EcdhXChachaAeadPublicKey.Merge(m, src) +} +func (m *EcdhXChachaAeadPublicKey) XXX_Size() int { + return xxx_messageInfo_EcdhXChachaAeadPublicKey.Size(m) +} +func (m *EcdhXChachaAeadPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_EcdhXChachaAeadPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EcdhXChachaAeadPublicKey proto.InternalMessageInfo + +func (m *EcdhXChachaAeadPublicKey) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *EcdhXChachaAeadPublicKey) GetParams() *EcdhAeadParams { + if m != nil { + return m.Params + } + return nil +} + +func (m *EcdhXChachaAeadPublicKey) GetKID() string { + if m != nil { + return m.KID + } + return "" +} + +func (m *EcdhXChachaAeadPublicKey) GetKeyValue() []byte { + if m != nil { + return m.KeyValue + } + return nil +} + +type EcdhXChachaAeadPrivateKey struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + PublicKey *EcdhXChachaAeadPublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + KeyValue []byte `protobuf:"bytes,3,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EcdhXChachaAeadPrivateKey) Reset() { *m = EcdhXChachaAeadPrivateKey{} } +func (m *EcdhXChachaAeadPrivateKey) String() string { return proto.CompactTextString(m) } +func (*EcdhXChachaAeadPrivateKey) ProtoMessage() {} +func (*EcdhXChachaAeadPrivateKey) Descriptor() ([]byte, []int) { + return fileDescriptor_62f9291a7083da43, []int{7} +} + +func (m *EcdhXChachaAeadPrivateKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EcdhXChachaAeadPrivateKey.Unmarshal(m, b) +} +func (m *EcdhXChachaAeadPrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EcdhXChachaAeadPrivateKey.Marshal(b, m, deterministic) +} +func (m *EcdhXChachaAeadPrivateKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EcdhXChachaAeadPrivateKey.Merge(m, src) +} +func (m *EcdhXChachaAeadPrivateKey) XXX_Size() int { + return xxx_messageInfo_EcdhXChachaAeadPrivateKey.Size(m) +} +func (m *EcdhXChachaAeadPrivateKey) XXX_DiscardUnknown() { + xxx_messageInfo_EcdhXChachaAeadPrivateKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EcdhXChachaAeadPrivateKey proto.InternalMessageInfo + +func (m *EcdhXChachaAeadPrivateKey) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *EcdhXChachaAeadPrivateKey) GetPublicKey() *EcdhXChachaAeadPublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *EcdhXChachaAeadPrivateKey) GetKeyValue() []byte { + if m != nil { + return m.KeyValue + } + return nil +} + func init() { proto.RegisterEnum("google.crypto.tink.KeyType", KeyType_name, KeyType_value) proto.RegisterType((*EcdhKwParams)(nil), "google.crypto.tink.EcdhKwParams") @@ -372,46 +490,50 @@ func init() { proto.RegisterType((*EcdhAeadPublicKey)(nil), "google.crypto.tink.EcdhAeadPublicKey") proto.RegisterType((*EcdhAeadPrivateKey)(nil), "google.crypto.tink.EcdhAeadPrivateKey") proto.RegisterType((*EcdhAeadKeyFormat)(nil), "google.crypto.tink.EcdhAeadKeyFormat") + proto.RegisterType((*EcdhXChachaAeadPublicKey)(nil), "google.crypto.tink.EcdhXChachaAeadPublicKey") + proto.RegisterType((*EcdhXChachaAeadPrivateKey)(nil), "google.crypto.tink.EcdhXChachaAeadPrivateKey") } func init() { proto.RegisterFile("proto/ecdh_aead.proto", fileDescriptor_62f9291a7083da43) } var fileDescriptor_62f9291a7083da43 = []byte{ - // 563 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x5f, 0x6b, 0x13, 0x4f, - 0x14, 0xfd, 0x4d, 0xfa, 0x33, 0xe9, 0x8e, 0x69, 0x5d, 0x07, 0x85, 0xd0, 0x0a, 0xd6, 0x85, 0x82, - 0x08, 0xdd, 0x48, 0x05, 0x1f, 0x0a, 0x3e, 0xd8, 0x76, 0x85, 0xb0, 0x90, 0x2c, 0x4b, 0x54, 0xea, - 0x83, 0xcb, 0x64, 0x72, 0xbb, 0x19, 0xf6, 0xcf, 0x0c, 0x93, 0x4d, 0xd2, 0xfd, 0x08, 0x82, 0x2f, - 0x3e, 0xf9, 0xee, 0x27, 0xf3, 0xa3, 0xc8, 0xcc, 0x6e, 0xd2, 0x54, 0xd3, 0xa2, 0x6f, 0xf7, 0xcc, - 0xde, 0x7b, 0xee, 0x39, 0x87, 0x99, 0xc5, 0x8f, 0xa5, 0x12, 0x85, 0xe8, 0x02, 0x1b, 0x4f, 0x22, - 0x0a, 0x74, 0xec, 0x1a, 0x4c, 0x48, 0x2c, 0x44, 0x9c, 0x82, 0xcb, 0x54, 0x29, 0x0b, 0xe1, 0x16, - 0x3c, 0x4f, 0xf6, 0x48, 0xd5, 0xca, 0x44, 0x96, 0x89, 0xbc, 0xea, 0xdb, 0xb3, 0xab, 0x33, 0xfd, - 0xbd, 0x3a, 0x71, 0xbe, 0x22, 0xdc, 0xf6, 0xd8, 0x78, 0xe2, 0x2f, 0x02, 0xaa, 0x68, 0x36, 0x25, - 0xe7, 0x18, 0xb3, 0x99, 0x9a, 0x43, 0x54, 0x94, 0x12, 0x3a, 0xe8, 0x00, 0x3d, 0xdf, 0x3d, 0x3e, - 0x74, 0xff, 0xe4, 0x77, 0xbd, 0x34, 0xe5, 0xb2, 0xe0, 0xec, 0x4c, 0x77, 0x0f, 0x4b, 0x09, 0xa1, - 0xc5, 0x96, 0x25, 0x79, 0x8d, 0xb7, 0x13, 0x28, 0x2b, 0x8e, 0x86, 0xe1, 0xd8, 0xdf, 0xc4, 0xe1, - 0x43, 0x69, 0x26, 0x5b, 0x49, 0x55, 0x38, 0x14, 0x3f, 0xd4, 0x6a, 0xde, 0x02, 0x1d, 0x7b, 0x39, - 0xab, 0x25, 0x9d, 0xe0, 0x6d, 0xed, 0x35, 0x82, 0x9c, 0x19, 0x41, 0xf7, 0x8f, 0x9f, 0xde, 0x46, - 0x06, 0x99, 0x4c, 0x69, 0x01, 0x61, 0x8b, 0x56, 0x0c, 0xc4, 0xc6, 0x5b, 0x67, 0x9e, 0x6f, 0x34, - 0xb4, 0x43, 0x5d, 0x3a, 0x3f, 0x11, 0xde, 0x5d, 0xee, 0xa8, 0x17, 0xbc, 0xc1, 0x56, 0xb2, 0x88, - 0xa4, 0x01, 0xf5, 0x86, 0x83, 0x8d, 0x96, 0xd7, 0x82, 0x0a, 0xb7, 0x93, 0xb5, 0xc8, 0x20, 0x67, - 0xcb, 0xf9, 0x86, 0x99, 0x3f, 0xbc, 0x6d, 0xfe, 0x86, 0xb5, 0xd0, 0x82, 0x95, 0xcb, 0x1e, 0x7e, - 0x00, 0x2c, 0x92, 0x82, 0xe7, 0x45, 0x74, 0x29, 0x54, 0x46, 0x8b, 0xce, 0x96, 0x49, 0xee, 0xd9, - 0x66, 0xaa, 0x40, 0x77, 0xbe, 0x33, 0x8d, 0xe1, 0x0e, 0xac, 0x43, 0xe7, 0x3b, 0xba, 0x8e, 0x31, - 0x98, 0x8d, 0x52, 0xce, 0x7c, 0x28, 0x49, 0x07, 0xb7, 0xe6, 0xa0, 0xa6, 0x5c, 0xe4, 0xc6, 0xe3, - 0x4e, 0xb8, 0x84, 0xe4, 0x04, 0x37, 0x6f, 0x88, 0x77, 0xee, 0x12, 0x5f, 0x2b, 0xaf, 0x27, 0x74, - 0xc0, 0x7e, 0xef, 0xdc, 0x48, 0xb5, 0x42, 0x5d, 0x92, 0x36, 0x46, 0x57, 0x9d, 0xff, 0x4d, 0xe0, - 0xe8, 0x4a, 0xa3, 0xb2, 0x73, 0xaf, 0x42, 0xa5, 0xf3, 0x0d, 0x61, 0xb2, 0x22, 0x52, 0x7c, 0x4e, - 0x0b, 0xb8, 0x5b, 0xda, 0x39, 0xc6, 0xd2, 0x38, 0x88, 0x12, 0x28, 0xff, 0x26, 0xdb, 0x95, 0xdf, - 0xd0, 0x92, 0x2b, 0xeb, 0xfb, 0xd8, 0xd2, 0xd7, 0x71, 0x4e, 0xd3, 0x19, 0x18, 0xa9, 0xed, 0x50, - 0xdf, 0xcf, 0x0f, 0x1a, 0x3b, 0x83, 0xeb, 0xb0, 0x7c, 0x28, 0xab, 0x08, 0xd7, 0x22, 0x41, 0xff, - 0x1a, 0xc9, 0x8b, 0x97, 0xb8, 0x55, 0x5f, 0x6c, 0xf2, 0x08, 0xdb, 0xef, 0xfb, 0x7e, 0x7f, 0xf0, - 0xb1, 0x1f, 0xf9, 0xde, 0x45, 0x34, 0xbc, 0x08, 0x3c, 0xfb, 0x3f, 0xd2, 0xc4, 0x0d, 0xef, 0xcc, - 0x46, 0xa4, 0x85, 0xb7, 0x06, 0x7e, 0x60, 0x37, 0x4e, 0xbf, 0x20, 0xfc, 0x84, 0x89, 0x6c, 0xd3, - 0x0e, 0xf3, 0x4c, 0x03, 0xf4, 0xe9, 0x73, 0xcc, 0x8b, 0xc9, 0x6c, 0xe4, 0x32, 0x91, 0x75, 0x27, - 0xa5, 0x04, 0x95, 0xc2, 0x38, 0x06, 0xd5, 0xa5, 0x8a, 0xc3, 0xf4, 0xe8, 0x52, 0xd1, 0x0c, 0x16, - 0x42, 0x25, 0x47, 0xb1, 0xe8, 0x56, 0xe3, 0xe6, 0x95, 0xd7, 0xa5, 0x54, 0x3c, 0xe3, 0x05, 0x9f, - 0x43, 0xf7, 0xb7, 0xff, 0x47, 0x14, 0x8b, 0xc8, 0x1c, 0xfd, 0x68, 0x34, 0x87, 0xbd, 0xbe, 0x1f, - 0x9c, 0x8e, 0x9a, 0x06, 0xbf, 0xfa, 0x15, 0x00, 0x00, 0xff, 0xff, 0x60, 0x55, 0xe5, 0xf0, 0x6b, - 0x04, 0x00, 0x00, + // 606 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x5d, 0x6b, 0x13, 0x41, + 0x14, 0x75, 0xd2, 0x9a, 0x34, 0xd7, 0xb4, 0xc6, 0x41, 0x21, 0xb6, 0x82, 0x75, 0xa1, 0x20, 0x62, + 0x13, 0xa9, 0xe0, 0x43, 0xc1, 0x07, 0x9b, 0xae, 0x50, 0x16, 0xd2, 0x65, 0xa9, 0x1f, 0xf5, 0xc1, + 0x65, 0x3a, 0xb9, 0x4d, 0x86, 0xfd, 0x98, 0x61, 0xba, 0x49, 0xbb, 0x3f, 0x41, 0xf0, 0xc5, 0x27, + 0x1f, 0x0b, 0xfe, 0x32, 0x7f, 0x8a, 0xcc, 0xec, 0x26, 0x4d, 0x6b, 0x5a, 0xea, 0x93, 0x6f, 0xf7, + 0xcc, 0xde, 0x7b, 0xe6, 0x9c, 0x33, 0xcb, 0x85, 0x47, 0x4a, 0xcb, 0x4c, 0x76, 0x90, 0xf7, 0x87, + 0x21, 0x43, 0xd6, 0x6f, 0x5b, 0x4c, 0xe9, 0x40, 0xca, 0x41, 0x8c, 0x6d, 0xae, 0x73, 0x95, 0xc9, + 0x76, 0x26, 0xd2, 0x68, 0x95, 0x16, 0xad, 0x5c, 0x26, 0x89, 0x4c, 0x8b, 0xbe, 0xd5, 0x66, 0x71, + 0x66, 0xbe, 0x17, 0x27, 0xce, 0x77, 0x02, 0x0d, 0x97, 0xf7, 0x87, 0xde, 0xa9, 0xcf, 0x34, 0x4b, + 0x4e, 0xe8, 0x2e, 0x00, 0x1f, 0xe9, 0x31, 0x86, 0x59, 0xae, 0xb0, 0x45, 0xd6, 0xc9, 0xf3, 0x95, + 0xad, 0x8d, 0xf6, 0xdf, 0xfc, 0x6d, 0x37, 0x8e, 0x85, 0xca, 0x04, 0xef, 0x9a, 0xee, 0x83, 0x5c, + 0x61, 0x50, 0xe7, 0x93, 0x92, 0xbe, 0x81, 0xa5, 0x08, 0xf3, 0x82, 0xa3, 0x62, 0x39, 0xd6, 0xe6, + 0x71, 0x78, 0x98, 0xdb, 0xc9, 0x5a, 0x54, 0x14, 0x0e, 0x83, 0x07, 0x46, 0xcd, 0x3b, 0x64, 0x7d, + 0x37, 0xe5, 0xa5, 0xa4, 0x6d, 0x58, 0x32, 0x5e, 0x43, 0x4c, 0xb9, 0x15, 0x74, 0x6f, 0xeb, 0xe9, + 0x75, 0x64, 0x98, 0xa8, 0x98, 0x65, 0x18, 0xd4, 0x58, 0xc1, 0x40, 0x9b, 0xb0, 0xd0, 0x75, 0x3d, + 0xab, 0xa1, 0x11, 0x98, 0xd2, 0xf9, 0x4d, 0x60, 0x65, 0x72, 0x47, 0x79, 0xc1, 0x5b, 0xa8, 0x47, + 0xa7, 0xa1, 0xb2, 0xa0, 0xbc, 0x61, 0x7d, 0xae, 0xe5, 0x99, 0xa0, 0x82, 0xa5, 0x68, 0x26, 0x32, + 0x4c, 0xf9, 0x64, 0xbe, 0x62, 0xe7, 0x37, 0xae, 0x9b, 0xbf, 0x64, 0x2d, 0xa8, 0xe3, 0xd4, 0xe5, + 0x1e, 0xdc, 0x47, 0x1e, 0x2a, 0x29, 0xd2, 0x2c, 0x3c, 0x96, 0x3a, 0x61, 0x59, 0x6b, 0xc1, 0x26, + 0xf7, 0x6c, 0x3e, 0x95, 0x6f, 0x3a, 0xdf, 0xdb, 0xc6, 0x60, 0x19, 0x67, 0xa1, 0xf3, 0x93, 0x5c, + 0xc4, 0xe8, 0x8f, 0x8e, 0x62, 0xc1, 0x3d, 0xcc, 0x69, 0x0b, 0x6a, 0x63, 0xd4, 0x27, 0x42, 0xa6, + 0xd6, 0xe3, 0x72, 0x30, 0x81, 0x74, 0x1b, 0xaa, 0x97, 0xc4, 0x3b, 0x37, 0x89, 0x2f, 0x95, 0x97, + 0x13, 0x26, 0x60, 0x6f, 0x6f, 0xd7, 0x4a, 0xad, 0x07, 0xa6, 0xa4, 0x0d, 0x20, 0x67, 0xad, 0x45, + 0x1b, 0x38, 0x39, 0x33, 0x28, 0x6f, 0xdd, 0x2d, 0x50, 0xee, 0xfc, 0x20, 0x40, 0xa7, 0x44, 0x5a, + 0x8c, 0x59, 0x86, 0x37, 0x4b, 0xdb, 0x05, 0x50, 0xd6, 0x41, 0x18, 0x61, 0x7e, 0x9b, 0x6c, 0xa7, + 0x7e, 0x83, 0xba, 0x9a, 0x5a, 0x5f, 0x83, 0xba, 0xf9, 0x1d, 0xc7, 0x2c, 0x1e, 0xa1, 0x95, 0xda, + 0x08, 0xcc, 0xff, 0xf9, 0xd1, 0x60, 0x67, 0xff, 0x22, 0x2c, 0x0f, 0xf3, 0x22, 0xc2, 0x99, 0x48, + 0xc8, 0xbf, 0x46, 0xe2, 0x9c, 0x13, 0x68, 0x99, 0x4f, 0x9f, 0xbb, 0x43, 0xc6, 0x87, 0xec, 0xff, + 0xbc, 0xc2, 0x25, 0xcb, 0x8b, 0x57, 0x2c, 0x9f, 0x13, 0x78, 0x7c, 0x55, 0xe1, 0x6d, 0x5e, 0xc3, + 0x9b, 0xf3, 0x1a, 0x2f, 0xaf, 0x93, 0x39, 0xcf, 0xfe, 0x6d, 0x1f, 0xe5, 0xc5, 0x2b, 0xa8, 0x95, + 0xcb, 0x81, 0x3e, 0x84, 0xe6, 0x87, 0x9e, 0xd7, 0xdb, 0xff, 0xd4, 0x0b, 0x3d, 0xf7, 0x30, 0x3c, + 0x38, 0xf4, 0xdd, 0xe6, 0x1d, 0x5a, 0x85, 0x8a, 0xdb, 0x6d, 0x12, 0x5a, 0x83, 0x85, 0x7d, 0xcf, + 0x6f, 0x56, 0x76, 0xbe, 0x11, 0x78, 0xc2, 0x65, 0x32, 0x4f, 0x8d, 0x5d, 0x75, 0x3e, 0xf9, 0xf2, + 0x75, 0x20, 0xb2, 0xe1, 0xe8, 0xa8, 0xcd, 0x65, 0xd2, 0x19, 0xe6, 0x0a, 0x75, 0x8c, 0xfd, 0x01, + 0xea, 0x0e, 0xd3, 0x02, 0x4f, 0x36, 0x8f, 0x35, 0x4b, 0xf0, 0x54, 0xea, 0x68, 0x73, 0x20, 0x3b, + 0xc5, 0xb8, 0xdd, 0x94, 0x65, 0xa9, 0xb4, 0x48, 0x44, 0x26, 0xc6, 0xd8, 0xb9, 0xb2, 0x83, 0xc3, + 0x81, 0x0c, 0xed, 0xd1, 0xaf, 0x4a, 0xf5, 0x60, 0xaf, 0xe7, 0xf9, 0x3b, 0x47, 0x55, 0x8b, 0x5f, + 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x2f, 0xb6, 0xa8, 0xc1, 0xaf, 0x05, 0x00, 0x00, } diff --git a/proto/tink/ecdh_aead.proto b/proto/tink/ecdh_aead.proto index 8cc99f9032..ab0d29f11f 100644 --- a/proto/tink/ecdh_aead.proto +++ b/proto/tink/ecdh_aead.proto @@ -61,7 +61,7 @@ message EcdhAeadParams { } // EcdhAeadPublicKey represents ECDHEncrypt primitive. -// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAeadPublicKey +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAesAeadPublicKey message EcdhAeadPublicKey { // Required. uint32 version = 1; @@ -82,7 +82,7 @@ message EcdhAeadPublicKey { } // EcdhAeadPrivateKey represents ECDHDecrypt primitive. -// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAeadPrivateKey +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhAesAeadPrivateKey message EcdhAeadPrivateKey { // Required. uint32 version = 1; @@ -97,4 +97,33 @@ message EcdhAeadPrivateKey { message EcdhAeadKeyFormat { // Required. EcdhAeadParams params = 1; +} + +// EcdhXChachaAeadPublicKey represents ECDHEncrypt primitive for XChacha20Poly1305 keys. +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPublicKey +message EcdhXChachaAeadPublicKey { + // Required. + uint32 version = 1; + + // Required. + EcdhAeadParams params = 2; + + // Required. + string KID = 3; + + // Required. + bytes key_value = 4; // Big integer in bigendian representation. +} + +// EcdhXChachaAeadPrivateKey represents ECDHDecrypt primitive for XChacha20Poly1305 keys. +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPrivateKey +message EcdhXChachaAeadPrivateKey { + // Required. + uint32 version = 1; + + // Required. + EcdhXChachaAeadPublicKey public_key = 2; + + // Required. + bytes key_value = 3; // Big integer in bigendian representation. } \ No newline at end of file