| // 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) |
| } |
| } |