Skip to content

Commit

Permalink
Introduce the ConfigV0 initial implementation. It is not complete and…
Browse files Browse the repository at this point in the history
… will be extended over time.

PiperOrigin-RevId: 700351139
Change-Id: Iec177aeace78569c9f0e54c0bdb0404db1a571a0
  • Loading branch information
LizaTretyakova authored and copybara-github committed Nov 26, 2024
1 parent 784e870 commit d618219
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 5 deletions.
8 changes: 3 additions & 5 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ import (
//
// This is an internal API.
type Config struct {
primitiveConstructors map[reflect.Type]primitiveConstructor
primitiveConstructors map[reflect.Type]func(key key.Key) (any, error)
keysetManagers map[string]registry.KeyManager
}

type primitiveConstructor func(key key.Key) (any, error)

// PrimitiveFromKeyData creates a primitive from the given [tinkpb.KeyData].
// Returns an error if there is no key manager registered for the given key
// type URL.
Expand Down Expand Up @@ -71,7 +69,7 @@ func (c *Config) PrimitiveFromKey(k key.Key, _ internalapi.Token) (any, error) {
// unless they are nil).
//
// This is an internal API.
func (c *Config) RegisterPrimitiveConstructor(keyType reflect.Type, constructor primitiveConstructor, _ internalapi.Token) error {
func (c *Config) RegisterPrimitiveConstructor(keyType reflect.Type, constructor func(key key.Key) (any, error), _ internalapi.Token) error {
if _, ok := c.primitiveConstructors[keyType]; ok {
return fmt.Errorf("RegisterPrimitiveConstructor: attempt to register a different primitive constructor for the same key type %v", keyType)
}
Expand All @@ -95,7 +93,7 @@ func (c *Config) RegisterKeyManager(keyTypeURL string, km registry.KeyManager, _
// New creates an empty Config.
func New() (*Config, error) {
return &Config{
primitiveConstructors: map[reflect.Type]primitiveConstructor{},
primitiveConstructors: map[reflect.Type]func(key key.Key) (any, error){},
keysetManagers: map[string]registry.KeyManager{},
}, nil
}
63 changes: 63 additions & 0 deletions internal/config/v0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config

import (
"fmt"

"github.com/tink-crypto/tink-go/v2/aead"
"github.com/tink-crypto/tink-go/v2/aead/aesctrhmac"
"github.com/tink-crypto/tink-go/v2/aead/aesgcm"
"github.com/tink-crypto/tink-go/v2/aead/chacha20poly1305"
"github.com/tink-crypto/tink-go/v2/aead/xchacha20poly1305"
"github.com/tink-crypto/tink-go/v2/internal/internalapi"
)

var configV0 = mustCreateConfigV0()

func mustCreateConfigV0() Config {
config, err := New()
if err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to create Config: %v", err))
}

if err = aesctrhmac.RegisterKeyManager(config, internalapi.Token{}); err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to register AES-CTR-HMAC: %v", err))
}

// TODO(b/286235179): Add RegisterPrimitiveConstructor for AES GCM.
if err = aesgcm.RegisterKeyManager(config, internalapi.Token{}); err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to register AES-GCM: %v", err))
}

if err = chacha20poly1305.RegisterKeyManager(config, internalapi.Token{}); err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to register CHACHA20-POLY1305: %v", err))
}

if err = xchacha20poly1305.RegisterKeyManager(config, internalapi.Token{}); err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to register XCHACHA20-POLY1305: %v", err))
}

if err = aead.RegisterKeyManager(config, internalapi.Token{}); err != nil {
panic(fmt.Sprintf("mustCreateConfigV0() failed to register AES-SIV: %v", err))
}

return *config
}

// V0 returns an instance of the ConfigV0.
func V0() Config {
return configV0
}
130 changes: 130 additions & 0 deletions internal/config/v0_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config_test

import (
"encoding/hex"
"reflect"
"testing"

"google.golang.org/protobuf/proto"
"github.com/tink-crypto/tink-go/v2/internal/config"
"github.com/tink-crypto/tink-go/v2/internal/internalapi"
"github.com/tink-crypto/tink-go/v2/testutil"
"github.com/tink-crypto/tink-go/v2/tink"
ctrpb "github.com/tink-crypto/tink-go/v2/proto/aes_ctr_go_proto"
achpb "github.com/tink-crypto/tink-go/v2/proto/aes_ctr_hmac_aead_go_proto"
aesgcmpb "github.com/tink-crypto/tink-go/v2/proto/aes_gcm_go_proto"
aesgcmsivpb "github.com/tink-crypto/tink-go/v2/proto/aes_gcm_siv_go_proto"
cc30p1305pb "github.com/tink-crypto/tink-go/v2/proto/chacha20_poly1305_go_proto"
commonpb "github.com/tink-crypto/tink-go/v2/proto/common_go_proto"
hmacpb "github.com/tink-crypto/tink-go/v2/proto/hmac_go_proto"
tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
xcc30p1305pb "github.com/tink-crypto/tink-go/v2/proto/xchacha20_poly1305_go_proto"
)

func TestConfigV0AEADKeyManagers(t *testing.T) {
configV0 := config.V0()

for _, test := range []struct {
typeURL string
key proto.Message
ciphertext string
}{
{
testutil.AESCTRHMACAEADTypeURL,
&achpb.AesCtrHmacAeadKey{
Version: 0,
AesCtrKey: &ctrpb.AesCtrKey{
Version: 0,
KeyValue: make([]byte, 32),
Params: &ctrpb.AesCtrParams{IvSize: 16},
},
HmacKey: &hmacpb.HmacKey{
Version: 0,
KeyValue: make([]byte, 32),
Params: &hmacpb.HmacParams{Hash: commonpb.HashType_SHA256, TagSize: 32},
},
},
"ad99a2c8aa74afdcac06b6b1ff9bddf156d27b8f08cf6a452b385596bd468ecfd3eee47d2a1054c178c9f0cc0e17fd5ec855f44d2b44935b03fa81e8e4882f059983f7de82c79046b6",
},
{
testutil.AESGCMTypeURL,
&aesgcmpb.AesGcmKey{
Version: testutil.AESGCMKeyVersion,
KeyValue: make([]byte, 32),
},
"78e5a9c49bcd68f212ab26ca1f08d173a2e842802488b805f73b4b902a2b9b51706d5cdefffcbf8dcc4506fa8706d9a3c71018dc11",
},
{
testutil.ChaCha20Poly1305TypeURL,
&cc30p1305pb.ChaCha20Poly1305Key{
Version: testutil.ChaCha20Poly1305KeyVersion,
KeyValue: make([]byte, 32),
},
"19af0737e87ced9c95d9e05afd2136ef084ec7635238e59e193bde2f9d5e44812aedd917b3ebcde0339cc3e3cd3b91f224768e9299",
},
{
testutil.XChaCha20Poly1305TypeURL,
&xcc30p1305pb.XChaCha20Poly1305Key{
Version: testutil.XChaCha20Poly1305KeyVersion,
KeyValue: make([]byte, 32),
},
"3a14e26b23a042cd0976ff846c27762edabf9c0bca6901f05891bdfd79dd98fb352c6ab2167883262a2b7a8508e0ebaf4ea08a02215b44518171b317190674a935",
},
{
testutil.AESGCMSIVTypeURL,
&aesgcmsivpb.AesGcmSivKey{
Version: testutil.AESGCMSIVKeyVersion,
KeyValue: make([]byte, 32),
},
"e3e3352092e8b0309f38192ec526c391fc65c963d92831f25699882c5203e2b7a4ce5d920ef736fc74120447325806a47dfc08f254",
},
} {
t.Run(test.typeURL, func(t *testing.T) {
serializedKey, err := proto.Marshal(test.key)
if err != nil {
t.Fatalf("proto.Marshal(%v): err=%v, want nil", test.key, err)
}
keyData := &tinkpb.KeyData{
TypeUrl: test.typeURL,
Value: serializedKey,
KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
}
aead, err := configV0.PrimitiveFromKeyData(keyData, internalapi.Token{})
if err != nil {
t.Fatalf("configV0.PrimitiveFromKeyData(%s) err=%v, want nil", test.typeURL, err)
}
a, ok := aead.(tink.AEAD)
if !ok {
t.Fatalf("aead was of type %v, want tink.AEAD", reflect.TypeOf(aead))
}

plaintext := "this is a test ciphertext"
aad := []byte("this is an aad")
ct, err := hex.DecodeString(test.ciphertext)
if err != nil {
t.Fatalf("hex.Decode(ciphertext) err=%v, want nil", err)
}
pt, err := a.Decrypt(ct, aad)
if err != nil {
t.Fatalf("aead.Decrypt known ciphertext err=%v, want nil", err)
}
if string(pt) != plaintext {
t.Errorf("Decrypted plaintext=%q, want %q", pt, plaintext)
}
})
}
}

0 comments on commit d618219

Please sign in to comment.