blob: 0eda45f77ab10438f9f822f40a00c9835f7ca872 [file] [log] [blame]
// Copyright 2022 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 hpke
import (
"fmt"
pb "github.com/google/tink/go/proto/hpke_go_proto"
)
// newPrimitivesFromProto constructs new KEM, KDF, AEADs from HpkeParams.
func newPrimitivesFromProto(params *pb.HpkeParams) (kem, kdf, aead, error) {
kemID, err := kemIDFromProto(params.GetKem())
if err != nil {
return nil, nil, nil, fmt.Errorf("kemIDFromProto(%d): %v", params.GetKem(), err)
}
kem, err := newKEM(kemID)
if err != nil {
return nil, nil, nil, fmt.Errorf("newKEM(%d): %v", kemID, err)
}
kdfID, err := kdfIDFromProto(params.GetKdf())
if err != nil {
return nil, nil, nil, fmt.Errorf("kdfIDFromProto(%d): %v", params.GetKdf(), err)
}
kdf, err := newKDF(kdfID)
if err != nil {
return nil, nil, nil, fmt.Errorf("newKDF(%d): %v", kdfID, err)
}
aeadID, err := aeadIDFromProto(params.GetAead())
if err != nil {
return nil, nil, nil, fmt.Errorf("aeadIDFromProto(%d): %v", params.GetAead(), err)
}
aead, err := newAEAD(aeadID)
if err != nil {
return nil, nil, nil, fmt.Errorf("newAEAD(%d): %v", aeadID, err)
}
return kem, kdf, aead, nil
}
// newKEM constructs a HPKE KEM using kemID, which are specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.1.
func newKEM(kemID uint16) (kem, error) {
if kemID == x25519HKDFSHA256 {
return newX25519KEM(sha256)
}
return nil, fmt.Errorf("KEM ID %d is not supported", kemID)
}
// kemIDFromProto returns the KEM ID from the HpkeKem enum value. KEM IDs are
// specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.1.
func kemIDFromProto(enum pb.HpkeKem) (uint16, error) {
if enum == pb.HpkeKem_DHKEM_X25519_HKDF_SHA256 {
return x25519HKDFSHA256, nil
}
return 0, fmt.Errorf("HpkeKem enum value %d is not supported", enum)
}
// newKDF constructs a HPKE KDF using kdfID, which are specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.2.
func newKDF(kdfID uint16) (kdf, error) {
if kdfID == hkdfSHA256 {
return newHKDFKDF(sha256)
}
return nil, fmt.Errorf("KDF ID %d is not supported", kdfID)
}
// kdfIDFromProto returns the KDF ID from the HpkeKdf enum value. KDF IDs are
// specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.2.
func kdfIDFromProto(enum pb.HpkeKdf) (uint16, error) {
if enum == pb.HpkeKdf_HKDF_SHA256 {
return hkdfSHA256, nil
}
return 0, fmt.Errorf("HpkeKdf enum value %d is not supported", enum)
}
// newAEAD constructs a HPKE AEAD using aeadID, which are specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3.
func newAEAD(aeadID uint16) (aead, error) {
switch aeadID {
case aes128GCM:
return newAESGCMAEAD(16)
case aes256GCM:
return newAESGCMAEAD(32)
case chaCha20Poly1305:
return &chaCha20Poly1305AEAD{}, nil
default:
return nil, fmt.Errorf("AEAD ID %d is not supported", aeadID)
}
}
// aeadIDFromProto returns the AEAD ID from the HpkeAead enum value. AEAD IDs
// are specified at
// https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3.
func aeadIDFromProto(enum pb.HpkeAead) (uint16, error) {
switch enum {
case pb.HpkeAead_AES_128_GCM:
return aes128GCM, nil
case pb.HpkeAead_AES_256_GCM:
return aes256GCM, nil
case pb.HpkeAead_CHACHA20_POLY1305:
return chaCha20Poly1305, nil
default:
return 0, fmt.Errorf("HpkeAead enum value %d is not supported", enum)
}
}