1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16
17 #include "tink/hybrid/internal/hpke_util.h"
18
19 #include "absl/strings/str_cat.h"
20 #include "tink/internal/ec_util.h"
21 #include "tink/subtle/common_enums.h"
22 #include "proto/hpke.pb.h"
23
24 namespace crypto {
25 namespace tink {
26 namespace internal {
27 namespace {
28
HpkeKemProtoToEnum(google::crypto::tink::HpkeKem kem)29 util::StatusOr<HpkeKem> HpkeKemProtoToEnum(google::crypto::tink::HpkeKem kem) {
30 switch (kem) {
31 case google::crypto::tink::HpkeKem::DHKEM_X25519_HKDF_SHA256:
32 return HpkeKem::kX25519HkdfSha256;
33 default:
34 return util::Status(
35 absl::StatusCode::kInvalidArgument,
36 absl::StrCat("Unable to convert unsupported HPKE KEM: ", kem));
37 }
38 }
39
HpkeKdfProtoToEnum(google::crypto::tink::HpkeKdf kdf)40 util::StatusOr<HpkeKdf> HpkeKdfProtoToEnum(google::crypto::tink::HpkeKdf kdf) {
41 switch (kdf) {
42 case google::crypto::tink::HpkeKdf::HKDF_SHA256:
43 return HpkeKdf::kHkdfSha256;
44 default:
45 return util::Status(
46 absl::StatusCode::kInvalidArgument,
47 absl::StrCat("Unable to convert unsupported HPKE KDF: ", kdf));
48 }
49 }
50
HpkeAeadProtoToEnum(google::crypto::tink::HpkeAead aead)51 util::StatusOr<HpkeAead> HpkeAeadProtoToEnum(
52 google::crypto::tink::HpkeAead aead) {
53 switch (aead) {
54 case google::crypto::tink::HpkeAead::AES_128_GCM:
55 return HpkeAead::kAes128Gcm;
56 case google::crypto::tink::HpkeAead::AES_256_GCM:
57 return HpkeAead::kAes256Gcm;
58 case google::crypto::tink::HpkeAead::CHACHA20_POLY1305:
59 return HpkeAead::kChaCha20Poly1305;
60 default:
61 return util::Status(
62 absl::StatusCode::kInvalidArgument,
63 absl::StrCat("Unable to convert unsupported HPKE AEAD: ", aead));
64 }
65 }
66
67 } // namespace
68
HpkeParamsProtoToStruct(google::crypto::tink::HpkeParams params)69 util::StatusOr<HpkeParams> HpkeParamsProtoToStruct(
70 google::crypto::tink::HpkeParams params) {
71 util::StatusOr<HpkeKem> kem = HpkeKemProtoToEnum(params.kem());
72 if (!kem.ok()) return kem.status();
73 util::StatusOr<HpkeKdf> kdf = HpkeKdfProtoToEnum(params.kdf());
74 if (!kdf.ok()) return kdf.status();
75 util::StatusOr<HpkeAead> aead = HpkeAeadProtoToEnum(params.aead());
76 if (!aead.ok()) return aead.status();
77 return HpkeParams{*kem, *kdf, *aead};
78 }
79
HpkeEncapsulatedKeyLength(google::crypto::tink::HpkeKem kem)80 util::StatusOr<int32_t> HpkeEncapsulatedKeyLength(
81 google::crypto::tink::HpkeKem kem) {
82 switch (kem) {
83 case google::crypto::tink::HpkeKem::DHKEM_X25519_HKDF_SHA256:
84 return internal::EcPointEncodingSizeInBytes(
85 subtle::EllipticCurveType::CURVE25519,
86 subtle::EcPointFormat::UNCOMPRESSED);
87 default:
88 return util::Status(
89 absl::StatusCode::kInvalidArgument,
90 absl::StrCat("Unable to determine KEM-encoding length for ", kem));
91 }
92 }
93
94 } // namespace internal
95 } // namespace tink
96 } // namespace crypto
97