Skip to content

Commit

Permalink
feat: first change for ECDH-1PU crypto primtive
Browse files Browse the repository at this point in the history
First change to introduce ECDH-1PU primitive:
Includes existing ecdh-es protobufs refactoring.
Includes introduction of composite_common proto file for sharing the common key type for both ECDH-ES and ECHD-1PU.

Follow up changes will include new key/primitive types, key managers, primitive factories, key templates, core primtive and 1PU key wrapping implementations.

part of hyperledger-archives#1806

Signed-off-by: Baha Shaaban <[email protected]>
  • Loading branch information
Baha Shaaban committed Jun 9, 2020
1 parent a10d75a commit 393965c
Show file tree
Hide file tree
Showing 29 changed files with 931 additions and 211 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package subtle
package composite

// package subtle provides the core crypto primitives to be used by composite primitives. It is intended for internal
// use only.
// package composite provides the core crypto composite primitives such as ECDH-ES and ECDH-1PU to be used by JWE crypto

// EncryptedData represents the Encryption's output data as a result of ECDHESEncrypt.Encrypt(pt, aad) call
// The user of the primitive must unmarshal the result and build their own ECDH-ES compliant message (ie JWE msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
tinkpb "github.com/google/tink/go/proto/tink_go_proto"

"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -68,7 +69,7 @@ func (km *ecdhesAESPrivateKeyManager) Primitive(serializedKey []byte) (interface

ptFormat := key.PublicKey.Params.EcPointFormat.String()

return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc, ecdhespb.KeyType_EC), nil
return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc, commonpb.KeyType_EC), nil
}

// NewKey creates a new key according to the specification of ECDHESPrivateKey format.
Expand All @@ -89,7 +90,7 @@ func (km *ecdhesAESPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.
return nil, errInvalidECDHESAESPrivateKeyFormat
}

keyFormat.Params.KwParams.KeyType = ecdhespb.KeyType_EC
keyFormat.Params.KwParams.KeyType = commonpb.KeyType_EC

pvt, err := hybrid.GenerateECDHKeyPair(curve)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import (
"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/ecdhes/subtle"
commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -58,15 +60,15 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{},
return nil, errInvalidECDHESAESPublicKey
}

var recipientsKeys []*subtle.PublicKey
var recipientsKeys []*composite.PublicKey

for _, recKey := range ecdhesPubKey.Params.KwParams.Recipients {
e := km.validateRecKey(recKey)
if e != nil {
return nil, errInvalidECDHESAESPublicKey
}

pub := &subtle.PublicKey{
pub := &composite.PublicKey{
KID: recKey.KID,
Type: recKey.KeyType.String(),
Curve: recKey.CurveType.String(),
Expand All @@ -84,7 +86,7 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{},

ptFormat := ecdhesPubKey.Params.EcPointFormat.String()

return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, ecdhespb.KeyType_EC), nil
return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, commonpb.KeyType_EC), nil
}

// DoesSupport indicates if this key manager supports the given key type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
tinkpb "github.com/google/tink/go/proto/tink_go_proto"
"github.com/stretchr/testify/require"

compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -216,21 +217,21 @@ func generateRecipients(t *testing.T) []*ecdhespb.EcdhesAeadRecipientPublicKey {
return []*ecdhespb.EcdhesAeadRecipientPublicKey{
{
Version: 0,
KeyType: ecdhespb.KeyType_EC,
KeyType: compositepb.KeyType_EC,
CurveType: curvProto,
X: recipient1Priv.PublicKey.Point.X.Bytes(),
Y: recipient1Priv.PublicKey.Point.Y.Bytes(),
},
{
Version: 0,
KeyType: ecdhespb.KeyType_EC,
KeyType: compositepb.KeyType_EC,
CurveType: curvProto,
X: recipient2Priv.PublicKey.Point.X.Bytes(),
Y: recipient2Priv.PublicKey.Point.Y.Bytes(),
},
{
Version: 0,
KeyType: ecdhespb.KeyType_EC,
KeyType: compositepb.KeyType_EC,
CurveType: curvProto,
X: recipient3Priv.PublicKey.Point.X.Bytes(),
Y: recipient3Priv.PublicKey.Point.Y.Bytes(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

commonpb "github.com/google/tink/go/proto/common_go_proto"

ecdhesaeadpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
)

// GetCurveType is a utility function that converts a string EC curve name into an EC curve proto type
Expand All @@ -29,12 +29,12 @@ func GetCurveType(curve string) (commonpb.EllipticCurveType, error) {
}

// GetKeyType is a utility function that converts a string type value into an proto KeyType
func GetKeyType(keyType string) (ecdhesaeadpb.KeyType, error) {
func GetKeyType(keyType string) (compositepb.KeyType, error) {
switch keyType {
case "EC":
return ecdhesaeadpb.KeyType_EC, nil
return compositepb.KeyType_EC, nil
case "OKP":
return ecdhesaeadpb.KeyType_OKP, nil
return compositepb.KeyType_OKP, nil
default:
return 0, fmt.Errorf("key type %s not supported", keyType)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
commonpb "github.com/google/tink/go/proto/common_go_proto"
"github.com/stretchr/testify/require"

ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
)

func TestGetCurveType(t *testing.T) {
Expand Down Expand Up @@ -124,25 +124,25 @@ func TestGetKeyType(t *testing.T) {
tcs := []struct {
tcName string
keyType string
expectedType ecdhespb.KeyType
expectedType compositepb.KeyType
isError bool
}{
{
"test get EC KeyType",
"EC",
ecdhespb.KeyType_EC,
compositepb.KeyType_EC,
false,
},
{
"test get OKP KeyType",
"OKP",
ecdhespb.KeyType_OKP,
compositepb.KeyType_OKP,
false,
},
{
"test get bad KeyType",
"bad",
ecdhespb.KeyType_UNKNOWN_KEY_TYPE,
compositepb.KeyType_UNKNOWN_KEY_TYPE,
true,
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import (
"github.com/google/tink/go/testutil"
"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -88,7 +89,7 @@ func TestECDHESFactory(t *testing.T) {
require.NoError(t, err)

// encrypt for single recipient will generate new AAD for recipient, extract it from ct
encData := &subtle.EncryptedData{}
encData := &composite.EncryptedData{}
err = json.Unmarshal(ct, encData)
require.NoError(t, err)

Expand All @@ -112,7 +113,7 @@ func ecdhesAEADPublicKey(t *testing.T, c commonpb.EllipticCurveType, ptfmt commo
// add recipients for Encryption primitive
Recipients: []*ecdhespb.EcdhesAeadRecipientPublicKey{
{
KeyType: ecdhespb.KeyType_EC,
KeyType: compositepb.KeyType_EC,
CurveType: c,
X: x,
Y: y,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (
hybrid "github.com/google/tink/go/hybrid/subtle"
tinkpb "github.com/google/tink/go/proto/tink_go_proto"

ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -86,7 +87,7 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
keyTypeName := pubKeyProto.Params.KwParams.KeyType.String()

// validate key type
if pubKeyProto.Params.KwParams.KeyType != ecdhespb.KeyType_EC {
if pubKeyProto.Params.KwParams.KeyType != commonpb.KeyType_EC {
return false, fmt.Errorf("undefined key type: '%s'", pubKeyProto.Params.KwParams.KeyType)
}

Expand All @@ -96,7 +97,7 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
return false, fmt.Errorf("undefined curve: %w", err)
}

pubKey := ecdhessubtle.PublicKey{
pubKey := composite.PublicKey{
KID: pubKeyProto.KID,
Type: keyTypeName,
Curve: curveName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
commonpb "github.com/google/tink/go/proto/common_go_proto"
tinkpb "github.com/google/tink/go/proto/tink_go_proto"

ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand Down Expand Up @@ -77,7 +77,7 @@ func getMarshalledProtoKeyAndKeyURL(pubKey []byte) ([]byte, string, error) {
}

func getMarshalledECDHESKey(pubKey []byte) ([]byte, error) {
ecPubKey := new(ecdhessubtle.PublicKey)
ecPubKey := new(composite.PublicKey)

err := json.Unmarshal(pubKey, ecPubKey)
if err != nil {
Expand All @@ -93,7 +93,7 @@ func getMarshalledECDHESKey(pubKey []byte) ([]byte, error) {
}
}

func getMarshalledECKey(ecPubKey *ecdhessubtle.PublicKey) ([]byte, error) {
func getMarshalledECKey(ecPubKey *composite.PublicKey) ([]byte, error) {
keyType, err := GetKeyType(ecPubKey.Type)
if err != nil {
return nil, fmt.Errorf("error on key type: %w", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
commonpb "github.com/google/tink/go/proto/common_go_proto"
tinkpb "github.com/google/tink/go/proto/tink_go_proto"

"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
)

Expand All @@ -24,23 +25,23 @@ import (
// Keys from this template represent a valid recipient public/private key pairs and can be stored in the KMS
func ECDHES256KWAES256GCMKeyTemplate() *tinkpb.KeyTemplate {
return createKeyTemplate(commonpb.EllipticCurveType_NIST_P256, commonpb.EcPointFormat_UNCOMPRESSED,
aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, nil, ecdhespb.KeyType_EC)
aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, nil, compositepb.KeyType_EC)
}

// ECDHES256KWAES256GCMKeyTemplateWithRecipients is similar to ECDHES256KWAES256GCMKeyTemplate but adding recipients
// keys 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
func ECDHES256KWAES256GCMKeyTemplateWithRecipients(recPublicKeys []subtle.PublicKey) (*tinkpb.KeyTemplate, error) {
func ECDHES256KWAES256GCMKeyTemplateWithRecipients(recPublicKeys []composite.PublicKey) (*tinkpb.KeyTemplate, error) {
ecdhesRecipientKeys, err := createECDHESPublicKeys(recPublicKeys)
if err != nil {
return nil, err
}

return createKeyTemplate(commonpb.EllipticCurveType_NIST_P256, commonpb.EcPointFormat_UNCOMPRESSED,
aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, ecdhesRecipientKeys, ecdhespb.KeyType_EC), nil
aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, ecdhesRecipientKeys, compositepb.KeyType_EC), nil
}

func createECDHESPublicKeys(recRawPublicKeys []subtle.PublicKey) ([]*ecdhespb.EcdhesAeadRecipientPublicKey, error) {
func createECDHESPublicKeys(recRawPublicKeys []composite.PublicKey) ([]*ecdhespb.EcdhesAeadRecipientPublicKey, error) {
var recKeys []*ecdhespb.EcdhesAeadRecipientPublicKey

for _, key := range recRawPublicKeys {
Expand Down Expand Up @@ -75,7 +76,7 @@ func createECDHESPublicKeys(recRawPublicKeys []subtle.PublicKey) ([]*ecdhespb.Ec
// size in bytes.
func createKeyTemplate(c commonpb.EllipticCurveType, epf commonpb.EcPointFormat, contentEncKeyT *tinkpb.KeyTemplate,
prefixType tinkpb.OutputPrefixType, recipients []*ecdhespb.EcdhesAeadRecipientPublicKey,
keyType ecdhespb.KeyType) *tinkpb.KeyTemplate {
keyType compositepb.KeyType) *tinkpb.KeyTemplate {
format := &ecdhespb.EcdhesAeadKeyFormat{
Params: &ecdhespb.EcdhesAeadParams{
KwParams: &ecdhespb.EcdhesKwParams{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/google/tink/go/keyset"
"github.com/stretchr/testify/require"

ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
)

func TestECDHESKeyTemplateTest(t *testing.T) {
Expand Down Expand Up @@ -50,17 +50,17 @@ func TestECDHESKeyTemplateTest(t *testing.T) {
}

// createRecipients and return their public key and keyset.Handle
func createRecipients(t *testing.T, numberOfRecipients int) ([]ecdhessubtle.PublicKey, []*keyset.Handle) {
func createRecipients(t *testing.T, numberOfRecipients int) ([]composite.PublicKey, []*keyset.Handle) {
t.Helper()

var (
r []ecdhessubtle.PublicKey
r []composite.PublicKey
rKH []*keyset.Handle
)

for i := 0; i < numberOfRecipients; i++ {
mrKey, kh := createAndMarshalRecipient(t)
ecPubKey := new(ecdhessubtle.PublicKey)
ecPubKey := new(composite.PublicKey)
err := json.Unmarshal(mrKey, ecPubKey)
require.NoError(t, err)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@ import (

hybrid "github.com/google/tink/go/hybrid/subtle"

ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite"
commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"
)

// package subtle provides the core crypto primitives to be used by ECDH-ES composite primitives. It is intended for
// internal use only.

// ECDHESAEADCompositeDecrypt is an instance of ECDH-ES decryption with Concat KDF
// and AEAD content decryption
type ECDHESAEADCompositeDecrypt struct {
privateKey *hybrid.ECPrivateKey
pointFormat string
encHelper EncrypterHelper
keyType ecdhespb.KeyType
keyType commonpb.KeyType
}

// NewECDHESAEADCompositeDecrypt returns ECDH-ES composite decryption construct with Concat KDF/ECDH-ES key unwrapping
// and AEAD payload decryption.
func NewECDHESAEADCompositeDecrypt(pvt *hybrid.ECPrivateKey, ptFormat string, encHelper EncrypterHelper,
keyType ecdhespb.KeyType) *ECDHESAEADCompositeDecrypt {
keyType commonpb.KeyType) *ECDHESAEADCompositeDecrypt {
return &ECDHESAEADCompositeDecrypt{
privateKey: pvt,
pointFormat: ptFormat,
Expand All @@ -46,7 +50,7 @@ func (d *ECDHESAEADCompositeDecrypt) Decrypt(ciphertext, aad []byte) ([]byte, er

var cek []byte

encData := new(EncryptedData)
encData := new(composite.EncryptedData)

err := json.Unmarshal(ciphertext, encData)
if err != nil {
Expand All @@ -55,7 +59,7 @@ func (d *ECDHESAEADCompositeDecrypt) Decrypt(ciphertext, aad []byte) ([]byte, er

// TODO: add support for Chacha content encryption https://github.com/hyperledger/aries-framework-go/issues/1684
switch d.keyType {
case ecdhespb.KeyType_EC:
case commonpb.KeyType_EC:
if encData.EncAlg != A256GCM {
return nil, fmt.Errorf("invalid content encryption algorihm '%s' for Decrypt()", encData.EncAlg)
}
Expand Down
Loading

0 comments on commit 393965c

Please sign in to comment.