grpc 1.38.0 → 1.39.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +50 -19
  3. data/include/grpc/event_engine/endpoint_config.h +48 -0
  4. data/include/grpc/event_engine/event_engine.h +13 -15
  5. data/include/grpc/event_engine/port.h +2 -0
  6. data/include/grpc/event_engine/slice_allocator.h +17 -7
  7. data/include/grpc/grpc.h +9 -2
  8. data/include/grpc/grpc_security.h +32 -0
  9. data/include/grpc/grpc_security_constants.h +1 -0
  10. data/include/grpc/impl/codegen/grpc_types.h +17 -13
  11. data/include/grpc/impl/codegen/port_platform.h +17 -0
  12. data/src/core/ext/filters/client_channel/client_channel.cc +2 -2
  13. data/src/core/ext/filters/client_channel/health/health_check_client.cc +2 -0
  14. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  15. data/src/core/ext/filters/client_channel/http_proxy.cc +16 -1
  16. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +755 -0
  17. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +10 -24
  19. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +63 -95
  20. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +1 -3
  21. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc +31 -0
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_event_engine.cc +28 -0
  23. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -3
  24. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +7 -2
  25. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +15 -3
  26. data/src/core/ext/filters/client_channel/retry_filter.cc +665 -404
  27. data/src/core/ext/filters/client_channel/retry_service_config.cc +43 -24
  28. data/src/core/ext/filters/client_channel/retry_service_config.h +8 -2
  29. data/src/core/ext/filters/client_idle/client_idle_filter.cc +1 -1
  30. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +6 -0
  31. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +2 -1
  32. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +3 -2
  33. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +10 -4
  34. data/src/core/ext/transport/chttp2/transport/internal.h +1 -0
  35. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -2
  36. data/src/core/ext/transport/inproc/inproc_transport.cc +42 -31
  37. data/src/core/ext/xds/xds_api.cc +247 -106
  38. data/src/core/ext/xds/xds_api.h +15 -6
  39. data/src/core/lib/address_utils/sockaddr_utils.cc +13 -0
  40. data/src/core/lib/address_utils/sockaddr_utils.h +10 -0
  41. data/src/core/lib/channel/channelz.h +3 -0
  42. data/src/core/lib/event_engine/endpoint_config.cc +46 -0
  43. data/src/core/lib/event_engine/endpoint_config_internal.h +42 -0
  44. data/src/core/lib/event_engine/event_engine.cc +50 -0
  45. data/src/core/lib/event_engine/slice_allocator.cc +33 -3
  46. data/src/core/lib/event_engine/sockaddr.cc +14 -12
  47. data/src/core/lib/event_engine/sockaddr.h +44 -0
  48. data/src/core/lib/gpr/wrap_memcpy.cc +2 -1
  49. data/src/core/lib/gprpp/status_helper.h +3 -0
  50. data/src/core/lib/iomgr/endpoint_pair_event_engine.cc +33 -0
  51. data/src/core/lib/iomgr/error.cc +5 -4
  52. data/src/core/lib/iomgr/error.h +1 -1
  53. data/src/core/lib/iomgr/event_engine/closure.cc +54 -0
  54. data/src/core/lib/iomgr/event_engine/closure.h +33 -0
  55. data/src/core/lib/iomgr/event_engine/endpoint.cc +194 -0
  56. data/src/core/lib/iomgr/event_engine/endpoint.h +53 -0
  57. data/src/core/lib/iomgr/event_engine/iomgr.cc +105 -0
  58. data/src/core/lib/iomgr/event_engine/iomgr.h +24 -0
  59. data/src/core/lib/iomgr/event_engine/pollset.cc +87 -0
  60. data/{include/grpc/event_engine/channel_args.h → src/core/lib/iomgr/event_engine/pollset.h} +7 -10
  61. data/src/core/lib/iomgr/event_engine/promise.h +51 -0
  62. data/src/core/lib/iomgr/event_engine/resolved_address_internal.cc +41 -0
  63. data/src/core/lib/iomgr/event_engine/resolved_address_internal.h +35 -0
  64. data/src/core/lib/iomgr/event_engine/resolver.cc +110 -0
  65. data/src/core/lib/iomgr/event_engine/tcp.cc +243 -0
  66. data/src/core/lib/iomgr/event_engine/timer.cc +57 -0
  67. data/src/core/lib/iomgr/exec_ctx.cc +8 -0
  68. data/src/core/lib/iomgr/exec_ctx.h +3 -4
  69. data/src/core/lib/iomgr/executor/threadpool.cc +2 -3
  70. data/src/core/lib/iomgr/executor/threadpool.h +2 -2
  71. data/src/core/lib/iomgr/iomgr.cc +1 -1
  72. data/src/core/lib/iomgr/iomgr_posix.cc +2 -0
  73. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +40 -10
  74. data/src/core/lib/iomgr/pollset_custom.cc +2 -2
  75. data/src/core/lib/iomgr/pollset_custom.h +3 -1
  76. data/src/core/lib/iomgr/pollset_uv.cc +3 -1
  77. data/src/core/lib/iomgr/pollset_uv.h +5 -1
  78. data/src/core/lib/iomgr/port.h +7 -5
  79. data/src/core/lib/iomgr/resolve_address.cc +5 -1
  80. data/src/core/lib/iomgr/resolve_address.h +6 -0
  81. data/src/core/lib/iomgr/sockaddr.h +1 -0
  82. data/src/core/lib/iomgr/socket_mutator.cc +15 -2
  83. data/src/core/lib/iomgr/socket_mutator.h +26 -2
  84. data/src/core/lib/iomgr/socket_utils_common_posix.cc +4 -4
  85. data/src/core/lib/iomgr/socket_utils_posix.h +2 -2
  86. data/src/core/lib/iomgr/tcp_client_posix.cc +7 -2
  87. data/src/core/lib/iomgr/tcp_posix.cc +42 -39
  88. data/src/core/lib/iomgr/tcp_posix.h +8 -0
  89. data/src/core/lib/iomgr/tcp_server_custom.cc +3 -4
  90. data/src/core/lib/iomgr/tcp_server_posix.cc +6 -0
  91. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +2 -1
  92. data/src/core/lib/iomgr/timer.h +6 -1
  93. data/src/core/lib/security/authorization/authorization_engine.h +44 -0
  94. data/src/core/lib/security/authorization/authorization_policy_provider.h +32 -0
  95. data/src/core/lib/security/authorization/authorization_policy_provider_vtable.cc +46 -0
  96. data/src/core/lib/security/authorization/evaluate_args.cc +209 -0
  97. data/src/core/lib/security/authorization/evaluate_args.h +91 -0
  98. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +3 -1
  99. data/src/core/lib/security/credentials/tls/tls_utils.cc +32 -0
  100. data/src/core/lib/security/credentials/tls/tls_utils.h +13 -0
  101. data/src/core/lib/security/security_connector/local/local_security_connector.cc +9 -6
  102. data/src/core/lib/security/security_connector/ssl_utils.cc +5 -0
  103. data/src/core/lib/surface/call.cc +21 -1
  104. data/src/core/lib/surface/call.h +11 -0
  105. data/src/core/lib/surface/completion_queue.cc +22 -22
  106. data/src/core/lib/surface/completion_queue.h +1 -1
  107. data/src/core/lib/surface/completion_queue_factory.cc +1 -2
  108. data/src/core/lib/surface/init.cc +1 -3
  109. data/src/core/lib/surface/init.h +10 -1
  110. data/src/core/lib/surface/version.cc +1 -1
  111. data/src/core/lib/transport/error_utils.cc +2 -2
  112. data/src/core/lib/transport/transport.h +2 -0
  113. data/src/core/lib/transport/transport_op_string.cc +1 -1
  114. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  115. data/src/core/tsi/alts/crypt/gsec.h +2 -0
  116. data/src/ruby/ext/grpc/extconf.rb +2 -0
  117. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +6 -0
  118. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +10 -1
  119. data/src/ruby/lib/grpc/version.rb +1 -1
  120. data/third_party/boringssl-with-bazel/err_data.c +269 -263
  121. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c +8 -6
  122. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/cipher_extra.c +4 -0
  123. data/third_party/boringssl-with-bazel/src/crypto/curve25519/curve25519.c +1 -1
  124. data/third_party/boringssl-with-bazel/src/crypto/curve25519/internal.h +1 -1
  125. data/third_party/boringssl-with-bazel/src/crypto/evp/evp.c +9 -0
  126. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/prime.c +0 -4
  127. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.c +7 -0
  128. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/md32_common.h +87 -121
  129. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/md4/md4.c +20 -30
  130. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/md5/md5.c +19 -30
  131. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/internal.h +1 -4
  132. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.c +0 -13
  133. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c +26 -24
  134. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c +10 -7
  135. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha1.c +28 -39
  136. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha256.c +48 -66
  137. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha512.c +4 -5
  138. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +362 -371
  139. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7_x509.c +4 -2
  140. data/third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c +2 -2
  141. data/third_party/boringssl-with-bazel/src/crypto/rsa_extra/rsa_asn1.c +1 -2
  142. data/third_party/boringssl-with-bazel/src/crypto/x509/internal.h +101 -11
  143. data/third_party/boringssl-with-bazel/src/crypto/x509/t_x509a.c +3 -0
  144. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +2 -2
  145. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c +3 -0
  146. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +1 -1
  147. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c +2 -0
  148. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +14 -15
  149. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vpm.c +53 -73
  150. data/third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c +31 -0
  151. data/third_party/boringssl-with-bazel/src/crypto/x509/x509rset.c +3 -0
  152. data/third_party/boringssl-with-bazel/src/crypto/x509/x_all.c +3 -0
  153. data/third_party/boringssl-with-bazel/src/crypto/x509/x_req.c +5 -8
  154. data/third_party/boringssl-with-bazel/src/crypto/x509/x_sig.c +5 -0
  155. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509a.c +3 -0
  156. data/third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h +7 -0
  157. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +1 -1
  158. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_utl.c +5 -8
  159. data/third_party/boringssl-with-bazel/src/include/openssl/aead.h +1 -1
  160. data/third_party/boringssl-with-bazel/src/include/openssl/arm_arch.h +66 -1
  161. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +40 -9
  162. data/third_party/boringssl-with-bazel/src/include/openssl/bytestring.h +1 -0
  163. data/third_party/boringssl-with-bazel/src/include/openssl/chacha.h +1 -1
  164. data/third_party/boringssl-with-bazel/src/include/openssl/digest.h +6 -2
  165. data/third_party/boringssl-with-bazel/src/include/openssl/ecdsa.h +14 -0
  166. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +19 -11
  167. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +325 -0
  168. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +23 -7
  169. data/third_party/boringssl-with-bazel/src/include/openssl/rsa.h +99 -63
  170. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +139 -109
  171. data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +12 -19
  172. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +48 -50
  173. data/third_party/boringssl-with-bazel/src/include/openssl/x509_vfy.h +451 -435
  174. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +0 -1
  175. data/third_party/boringssl-with-bazel/src/ssl/d1_both.cc +2 -2
  176. data/third_party/boringssl-with-bazel/src/ssl/d1_srtp.cc +1 -1
  177. data/third_party/boringssl-with-bazel/src/ssl/encrypted_client_hello.cc +773 -84
  178. data/third_party/boringssl-with-bazel/src/ssl/handoff.cc +80 -47
  179. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +24 -19
  180. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +189 -86
  181. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +45 -56
  182. data/third_party/boringssl-with-bazel/src/ssl/internal.h +272 -167
  183. data/third_party/boringssl-with-bazel/src/ssl/s3_both.cc +2 -2
  184. data/third_party/boringssl-with-bazel/src/ssl/s3_lib.cc +2 -2
  185. data/third_party/boringssl-with-bazel/src/ssl/s3_pkt.cc +14 -19
  186. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +34 -102
  187. data/third_party/boringssl-with-bazel/src/ssl/ssl_privkey.cc +2 -0
  188. data/third_party/boringssl-with-bazel/src/ssl/ssl_session.cc +8 -31
  189. data/third_party/boringssl-with-bazel/src/ssl/ssl_stat.cc +3 -0
  190. data/third_party/boringssl-with-bazel/src/ssl/ssl_transcript.cc +4 -3
  191. data/third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc +7 -3
  192. data/third_party/boringssl-with-bazel/src/ssl/t1_lib.cc +576 -648
  193. data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +31 -3
  194. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +98 -39
  195. data/third_party/boringssl-with-bazel/src/ssl/tls13_enc.cc +141 -94
  196. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +58 -68
  197. metadata +65 -40
  198. data/third_party/boringssl-with-bazel/src/crypto/hpke/internal.h +0 -267
  199. data/third_party/boringssl-with-bazel/src/crypto/x509/vpm_int.h +0 -71
@@ -162,7 +162,7 @@ static void sha512_block_data_order(uint64_t *state, const uint8_t *in,
162
162
 
163
163
  int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], SHA512_CTX *sha) {
164
164
  // |SHA384_Init| sets |sha->md_len| to |SHA384_DIGEST_LENGTH|, so this has a
165
- // |smaller output.
165
+ // smaller output.
166
166
  assert(sha->md_len == SHA384_DIGEST_LENGTH);
167
167
  return sha512_final_impl(out, sha);
168
168
  }
@@ -237,7 +237,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
237
237
  int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) {
238
238
  // Ideally we would assert |sha->md_len| is |SHA512_DIGEST_LENGTH| to match
239
239
  // the size hint, but calling code often pairs |SHA384_Init| with
240
- // |SHA512_Final| and expects |sha->md_len| to carry the over.
240
+ // |SHA512_Final| and expects |sha->md_len| to carry the size over.
241
241
  //
242
242
  // TODO(davidben): Add an assert and fix code to match them up.
243
243
  return sha512_final_impl(out, sha);
@@ -270,9 +270,8 @@ static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha) {
270
270
  assert(sha->md_len % 8 == 0);
271
271
  const size_t out_words = sha->md_len / 8;
272
272
  for (size_t i = 0; i < out_words; i++) {
273
- const uint64_t t = CRYPTO_bswap8(sha->h[i]);
274
- memcpy(out, &t, sizeof(t));
275
- out += sizeof(t);
273
+ CRYPTO_store_u64_be(out, sha->h[i]);
274
+ out += 8;
276
275
  }
277
276
 
278
277
  return 1;
@@ -12,6 +12,8 @@
12
12
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
13
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
14
 
15
+ #include <openssl/hpke.h>
16
+
15
17
  #include <assert.h>
16
18
  #include <string.h>
17
19
 
@@ -22,47 +24,54 @@
22
24
  #include <openssl/err.h>
23
25
  #include <openssl/evp_errors.h>
24
26
  #include <openssl/hkdf.h>
27
+ #include <openssl/rand.h>
25
28
  #include <openssl/sha.h>
26
29
 
27
30
  #include "../internal.h"
28
- #include "internal.h"
29
31
 
30
32
 
31
- // This file implements draft-irtf-cfrg-hpke-07.
33
+ // This file implements draft-irtf-cfrg-hpke-08.
32
34
 
33
- #define KEM_CONTEXT_LEN (2 * X25519_PUBLIC_VALUE_LEN)
35
+ #define MAX_SEED_LEN X25519_PRIVATE_KEY_LEN
36
+ #define MAX_SHARED_SECRET_LEN SHA256_DIGEST_LENGTH
34
37
 
35
- // This is strlen("HPKE") + 3 * sizeof(uint16_t).
36
- #define HPKE_SUITE_ID_LEN 10
38
+ struct evp_hpke_kem_st {
39
+ uint16_t id;
40
+ size_t public_key_len;
41
+ size_t private_key_len;
42
+ size_t seed_len;
43
+ int (*init_key)(EVP_HPKE_KEY *key, const uint8_t *priv_key,
44
+ size_t priv_key_len);
45
+ int (*generate_key)(EVP_HPKE_KEY *key);
46
+ int (*encap_with_seed)(const EVP_HPKE_KEM *kem, uint8_t *out_shared_secret,
47
+ size_t *out_shared_secret_len, uint8_t *out_enc,
48
+ size_t *out_enc_len, size_t max_enc,
49
+ const uint8_t *peer_public_key,
50
+ size_t peer_public_key_len, const uint8_t *seed,
51
+ size_t seed_len);
52
+ int (*decap)(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret,
53
+ size_t *out_shared_secret_len, const uint8_t *enc,
54
+ size_t enc_len);
55
+ };
37
56
 
38
- #define HPKE_MODE_BASE 0
39
- #define HPKE_MODE_PSK 1
57
+ struct evp_hpke_kdf_st {
58
+ uint16_t id;
59
+ // We only support HKDF-based KDFs.
60
+ const EVP_MD *(*hkdf_md_func)(void);
61
+ };
40
62
 
41
- static const char kHpkeRfcId[] = "HPKE-07";
63
+ struct evp_hpke_aead_st {
64
+ uint16_t id;
65
+ const EVP_AEAD *(*aead_func)(void);
66
+ };
42
67
 
43
- static int add_label_string(CBB *cbb, const char *label) {
44
- return CBB_add_bytes(cbb, (const uint8_t *)label, strlen(label));
45
- }
46
68
 
47
- // The suite_id for the KEM is defined as concat("KEM", I2OSP(kem_id, 2)). Note
48
- // that the suite_id used outside of the KEM also includes the kdf_id and
49
- // aead_id.
50
- static const uint8_t kX25519SuiteID[] = {
51
- 'K', 'E', 'M', EVP_HPKE_DHKEM_X25519_HKDF_SHA256 >> 8,
52
- EVP_HPKE_DHKEM_X25519_HKDF_SHA256 & 0x00ff};
69
+ // Low-level labeled KDF functions.
53
70
 
54
- // The suite_id for non-KEM pieces of HPKE is defined as concat("HPKE",
55
- // I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)).
56
- static int hpke_build_suite_id(uint8_t out[HPKE_SUITE_ID_LEN], uint16_t kdf_id,
57
- uint16_t aead_id) {
58
- CBB cbb;
59
- int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) &&
60
- add_label_string(&cbb, "HPKE") &&
61
- CBB_add_u16(&cbb, EVP_HPKE_DHKEM_X25519_HKDF_SHA256) &&
62
- CBB_add_u16(&cbb, kdf_id) &&
63
- CBB_add_u16(&cbb, aead_id);
64
- CBB_cleanup(&cbb);
65
- return ret;
71
+ static const char kHpkeVersionId[] = "HPKE-v1";
72
+
73
+ static int add_label_string(CBB *cbb, const char *label) {
74
+ return CBB_add_bytes(cbb, (const uint8_t *)label, strlen(label));
66
75
  }
67
76
 
68
77
  static int hpke_labeled_extract(const EVP_MD *hkdf_md, uint8_t *out_key,
@@ -70,10 +79,10 @@ static int hpke_labeled_extract(const EVP_MD *hkdf_md, uint8_t *out_key,
70
79
  size_t salt_len, const uint8_t *suite_id,
71
80
  size_t suite_id_len, const char *label,
72
81
  const uint8_t *ikm, size_t ikm_len) {
73
- // labeledIKM = concat("RFCXXXX ", suite_id, label, IKM)
82
+ // labeledIKM = concat("HPKE-v1", suite_id, label, IKM)
74
83
  CBB labeled_ikm;
75
84
  int ok = CBB_init(&labeled_ikm, 0) &&
76
- add_label_string(&labeled_ikm, kHpkeRfcId) &&
85
+ add_label_string(&labeled_ikm, kHpkeVersionId) &&
77
86
  CBB_add_bytes(&labeled_ikm, suite_id, suite_id_len) &&
78
87
  add_label_string(&labeled_ikm, label) &&
79
88
  CBB_add_bytes(&labeled_ikm, ikm, ikm_len) &&
@@ -88,11 +97,11 @@ static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
88
97
  size_t prk_len, const uint8_t *suite_id,
89
98
  size_t suite_id_len, const char *label,
90
99
  const uint8_t *info, size_t info_len) {
91
- // labeledInfo = concat(I2OSP(L, 2), "RFCXXXX ", suite_id, label, info)
100
+ // labeledInfo = concat(I2OSP(L, 2), "HPKE-v1", suite_id, label, info)
92
101
  CBB labeled_info;
93
102
  int ok = CBB_init(&labeled_info, 0) &&
94
103
  CBB_add_u16(&labeled_info, out_len) &&
95
- add_label_string(&labeled_info, kHpkeRfcId) &&
104
+ add_label_string(&labeled_info, kHpkeVersionId) &&
96
105
  CBB_add_bytes(&labeled_info, suite_id, suite_id_len) &&
97
106
  add_label_string(&labeled_info, label) &&
98
107
  CBB_add_bytes(&labeled_info, info, info_len) &&
@@ -102,110 +111,263 @@ static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
102
111
  return ok;
103
112
  }
104
113
 
105
- static int hpke_extract_and_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
106
- size_t out_len,
107
- const uint8_t dh[X25519_PUBLIC_VALUE_LEN],
108
- const uint8_t kem_context[KEM_CONTEXT_LEN]) {
114
+
115
+ // KEM implementations.
116
+
117
+ // dhkem_extract_and_expand implements the ExtractAndExpand operation in the
118
+ // DHKEM construction. See section 4.1 of draft-irtf-cfrg-hpke-08.
119
+ static int dhkem_extract_and_expand(uint16_t kem_id, const EVP_MD *hkdf_md,
120
+ uint8_t *out_key, size_t out_len,
121
+ const uint8_t *dh, size_t dh_len,
122
+ const uint8_t *kem_context,
123
+ size_t kem_context_len) {
124
+ // concat("KEM", I2OSP(kem_id, 2))
125
+ uint8_t suite_id[5] = {'K', 'E', 'M', kem_id >> 8, kem_id & 0xff};
109
126
  uint8_t prk[EVP_MAX_MD_SIZE];
110
127
  size_t prk_len;
111
- static const char kEaePrkLabel[] = "eae_prk";
112
- if (!hpke_labeled_extract(hkdf_md, prk, &prk_len, NULL, 0, kX25519SuiteID,
113
- sizeof(kX25519SuiteID), kEaePrkLabel, dh,
114
- X25519_PUBLIC_VALUE_LEN)) {
128
+ return hpke_labeled_extract(hkdf_md, prk, &prk_len, NULL, 0, suite_id,
129
+ sizeof(suite_id), "eae_prk", dh, dh_len) &&
130
+ hpke_labeled_expand(hkdf_md, out_key, out_len, prk, prk_len, suite_id,
131
+ sizeof(suite_id), "shared_secret", kem_context,
132
+ kem_context_len);
133
+ }
134
+
135
+ static int x25519_init_key(EVP_HPKE_KEY *key, const uint8_t *priv_key,
136
+ size_t priv_key_len) {
137
+ if (priv_key_len != X25519_PRIVATE_KEY_LEN) {
138
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
115
139
  return 0;
116
140
  }
117
- static const char kPRKExpandLabel[] = "shared_secret";
118
- if (!hpke_labeled_expand(hkdf_md, out_key, out_len, prk, prk_len,
119
- kX25519SuiteID, sizeof(kX25519SuiteID),
120
- kPRKExpandLabel, kem_context, KEM_CONTEXT_LEN)) {
141
+
142
+ OPENSSL_memcpy(key->private_key, priv_key, priv_key_len);
143
+ X25519_public_from_private(key->public_key, priv_key);
144
+ return 1;
145
+ }
146
+
147
+ static int x25519_generate_key(EVP_HPKE_KEY *key) {
148
+ X25519_keypair(key->public_key, key->private_key);
149
+ return 1;
150
+ }
151
+
152
+ static int x25519_encap_with_seed(
153
+ const EVP_HPKE_KEM *kem, uint8_t *out_shared_secret,
154
+ size_t *out_shared_secret_len, uint8_t *out_enc, size_t *out_enc_len,
155
+ size_t max_enc, const uint8_t *peer_public_key, size_t peer_public_key_len,
156
+ const uint8_t *seed, size_t seed_len) {
157
+ if (max_enc < X25519_PUBLIC_VALUE_LEN) {
158
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
159
+ return 0;
160
+ }
161
+ if (seed_len != X25519_PRIVATE_KEY_LEN) {
162
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
163
+ return 0;
164
+ }
165
+ X25519_public_from_private(out_enc, seed);
166
+
167
+ uint8_t dh[X25519_SHARED_KEY_LEN];
168
+ if (peer_public_key_len != X25519_PUBLIC_VALUE_LEN ||
169
+ !X25519(dh, seed, peer_public_key)) {
170
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
171
+ return 0;
172
+ }
173
+
174
+ uint8_t kem_context[2 * X25519_PUBLIC_VALUE_LEN];
175
+ OPENSSL_memcpy(kem_context, out_enc, X25519_PUBLIC_VALUE_LEN);
176
+ OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, peer_public_key,
177
+ X25519_PUBLIC_VALUE_LEN);
178
+ if (!dhkem_extract_and_expand(kem->id, EVP_sha256(), out_shared_secret,
179
+ SHA256_DIGEST_LENGTH, dh, sizeof(dh),
180
+ kem_context, sizeof(kem_context))) {
121
181
  return 0;
122
182
  }
183
+
184
+ *out_enc_len = X25519_PUBLIC_VALUE_LEN;
185
+ *out_shared_secret_len = SHA256_DIGEST_LENGTH;
123
186
  return 1;
124
187
  }
125
188
 
126
- uint16_t EVP_HPKE_CTX_get_aead_id(const EVP_HPKE_CTX *hpke) {
127
- return hpke->aead_id;
189
+ static int x25519_decap(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret,
190
+ size_t *out_shared_secret_len, const uint8_t *enc,
191
+ size_t enc_len) {
192
+ uint8_t dh[X25519_SHARED_KEY_LEN];
193
+ if (enc_len != X25519_PUBLIC_VALUE_LEN ||
194
+ !X25519(dh, key->private_key, enc)) {
195
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
196
+ return 0;
197
+ }
198
+
199
+ uint8_t kem_context[2 * X25519_PUBLIC_VALUE_LEN];
200
+ OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN);
201
+ OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, key->public_key,
202
+ X25519_PUBLIC_VALUE_LEN);
203
+ if (!dhkem_extract_and_expand(key->kem->id, EVP_sha256(), out_shared_secret,
204
+ SHA256_DIGEST_LENGTH, dh, sizeof(dh),
205
+ kem_context, sizeof(kem_context))) {
206
+ return 0;
207
+ }
208
+
209
+ *out_shared_secret_len = SHA256_DIGEST_LENGTH;
210
+ return 1;
211
+ }
212
+
213
+ const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void) {
214
+ static const EVP_HPKE_KEM kKEM = {
215
+ /*id=*/EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
216
+ /*public_key_len=*/X25519_PUBLIC_VALUE_LEN,
217
+ /*private_key_len=*/X25519_PRIVATE_KEY_LEN,
218
+ /*seed_len=*/X25519_PRIVATE_KEY_LEN,
219
+ x25519_init_key,
220
+ x25519_generate_key,
221
+ x25519_encap_with_seed,
222
+ x25519_decap,
223
+ };
224
+ return &kKEM;
128
225
  }
129
226
 
130
- uint16_t EVP_HPKE_CTX_get_kdf_id(const EVP_HPKE_CTX *hpke) {
131
- return hpke->kdf_id;
227
+ uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem) { return kem->id; }
228
+
229
+ void EVP_HPKE_KEY_zero(EVP_HPKE_KEY *key) {
230
+ OPENSSL_memset(key, 0, sizeof(EVP_HPKE_KEY));
231
+ }
232
+
233
+ void EVP_HPKE_KEY_cleanup(EVP_HPKE_KEY *key) {
234
+ // Nothing to clean up for now, but we may introduce a cleanup process in the
235
+ // future.
236
+ }
237
+
238
+ int EVP_HPKE_KEY_copy(EVP_HPKE_KEY *dst, const EVP_HPKE_KEY *src) {
239
+ // For now, |EVP_HPKE_KEY| is trivially copyable.
240
+ OPENSSL_memcpy(dst, src, sizeof(EVP_HPKE_KEY));
241
+ return 1;
132
242
  }
133
243
 
134
- const EVP_AEAD *EVP_HPKE_get_aead(uint16_t aead_id) {
135
- switch (aead_id) {
136
- case EVP_HPKE_AEAD_AES_128_GCM:
137
- return EVP_aead_aes_128_gcm();
138
- case EVP_HPKE_AEAD_AES_256_GCM:
139
- return EVP_aead_aes_256_gcm();
140
- case EVP_HPKE_AEAD_CHACHA20POLY1305:
141
- return EVP_aead_chacha20_poly1305();
244
+ int EVP_HPKE_KEY_init(EVP_HPKE_KEY *key, const EVP_HPKE_KEM *kem,
245
+ const uint8_t *priv_key, size_t priv_key_len) {
246
+ EVP_HPKE_KEY_zero(key);
247
+ key->kem = kem;
248
+ if (!kem->init_key(key, priv_key, priv_key_len)) {
249
+ key->kem = NULL;
250
+ return 0;
142
251
  }
143
- OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
144
- return NULL;
145
- }
146
-
147
- const EVP_MD *EVP_HPKE_get_hkdf_md(uint16_t kdf_id) {
148
- switch (kdf_id) {
149
- case EVP_HPKE_HKDF_SHA256:
150
- return EVP_sha256();
151
- case EVP_HPKE_HKDF_SHA384:
152
- return EVP_sha384();
153
- case EVP_HPKE_HKDF_SHA512:
154
- return EVP_sha512();
252
+ return 1;
253
+ }
254
+
255
+ int EVP_HPKE_KEY_generate(EVP_HPKE_KEY *key, const EVP_HPKE_KEM *kem) {
256
+ EVP_HPKE_KEY_zero(key);
257
+ key->kem = kem;
258
+ if (!kem->generate_key(key)) {
259
+ key->kem = NULL;
260
+ return 0;
155
261
  }
156
- OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
157
- return NULL;
262
+ return 1;
158
263
  }
159
264
 
160
- static int hpke_key_schedule(EVP_HPKE_CTX *hpke, uint8_t mode,
161
- const uint8_t *shared_secret,
162
- size_t shared_secret_len, const uint8_t *info,
163
- size_t info_len, const uint8_t *psk,
164
- size_t psk_len, const uint8_t *psk_id,
165
- size_t psk_id_len) {
166
- // Verify the PSK inputs.
167
- switch (mode) {
168
- case HPKE_MODE_BASE:
169
- // This is an internal error, unreachable from the caller.
170
- assert(psk_len == 0 && psk_id_len == 0);
171
- break;
172
- case HPKE_MODE_PSK:
173
- if (psk_len == 0 || psk_id_len == 0) {
174
- OPENSSL_PUT_ERROR(EVP, EVP_R_EMPTY_PSK);
175
- return 0;
176
- }
177
- break;
178
- default:
179
- return 0;
265
+ const EVP_HPKE_KEM *EVP_HPKE_KEY_kem(const EVP_HPKE_KEY *key) {
266
+ return key->kem;
267
+ }
268
+
269
+ int EVP_HPKE_KEY_public_key(const EVP_HPKE_KEY *key, uint8_t *out,
270
+ size_t *out_len, size_t max_out) {
271
+ if (max_out < key->kem->public_key_len) {
272
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
273
+ return 0;
180
274
  }
275
+ OPENSSL_memcpy(out, key->public_key, key->kem->public_key_len);
276
+ *out_len = key->kem->public_key_len;
277
+ return 1;
278
+ }
181
279
 
182
- // Attempt to get an EVP_AEAD*.
183
- const EVP_AEAD *aead = EVP_HPKE_get_aead(hpke->aead_id);
184
- if (aead == NULL) {
280
+ int EVP_HPKE_KEY_private_key(const EVP_HPKE_KEY *key, uint8_t *out,
281
+ size_t *out_len, size_t max_out) {
282
+ if (max_out < key->kem->private_key_len) {
283
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
185
284
  return 0;
186
285
  }
286
+ OPENSSL_memcpy(out, key->private_key, key->kem->private_key_len);
287
+ *out_len = key->kem->private_key_len;
288
+ return 1;
289
+ }
290
+
291
+
292
+ // Supported KDFs and AEADs.
293
+
294
+ const EVP_HPKE_KDF *EVP_hpke_hkdf_sha256(void) {
295
+ static const EVP_HPKE_KDF kKDF = {EVP_HPKE_HKDF_SHA256, &EVP_sha256};
296
+ return &kKDF;
297
+ }
298
+
299
+ uint16_t EVP_HPKE_KDF_id(const EVP_HPKE_KDF *kdf) { return kdf->id; }
300
+
301
+ const EVP_HPKE_AEAD *EVP_hpke_aes_128_gcm(void) {
302
+ static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_AES_128_GCM,
303
+ &EVP_aead_aes_128_gcm};
304
+ return &kAEAD;
305
+ }
306
+
307
+ const EVP_HPKE_AEAD *EVP_hpke_aes_256_gcm(void) {
308
+ static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_AES_256_GCM,
309
+ &EVP_aead_aes_256_gcm};
310
+ return &kAEAD;
311
+ }
312
+
313
+ const EVP_HPKE_AEAD *EVP_hpke_chacha20_poly1305(void) {
314
+ static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_CHACHA20_POLY1305,
315
+ &EVP_aead_chacha20_poly1305};
316
+ return &kAEAD;
317
+ }
318
+
319
+ uint16_t EVP_HPKE_AEAD_id(const EVP_HPKE_AEAD *aead) { return aead->id; }
320
+
321
+ const EVP_AEAD *EVP_HPKE_AEAD_aead(const EVP_HPKE_AEAD *aead) {
322
+ return aead->aead_func();
323
+ }
324
+
325
+
326
+ // HPKE implementation.
327
+
328
+ // This is strlen("HPKE") + 3 * sizeof(uint16_t).
329
+ #define HPKE_SUITE_ID_LEN 10
330
+
331
+ // The suite_id for non-KEM pieces of HPKE is defined as concat("HPKE",
332
+ // I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)).
333
+ static int hpke_build_suite_id(const EVP_HPKE_CTX *ctx,
334
+ uint8_t out[HPKE_SUITE_ID_LEN]) {
335
+ CBB cbb;
336
+ int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) &&
337
+ add_label_string(&cbb, "HPKE") &&
338
+ CBB_add_u16(&cbb, EVP_HPKE_DHKEM_X25519_HKDF_SHA256) &&
339
+ CBB_add_u16(&cbb, ctx->kdf->id) &&
340
+ CBB_add_u16(&cbb, ctx->aead->id);
341
+ CBB_cleanup(&cbb);
342
+ return ret;
343
+ }
344
+
345
+ #define HPKE_MODE_BASE 0
187
346
 
347
+ static int hpke_key_schedule(EVP_HPKE_CTX *ctx, const uint8_t *shared_secret,
348
+ size_t shared_secret_len, const uint8_t *info,
349
+ size_t info_len) {
188
350
  uint8_t suite_id[HPKE_SUITE_ID_LEN];
189
- if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
351
+ if (!hpke_build_suite_id(ctx, suite_id)) {
190
352
  return 0;
191
353
  }
192
354
 
193
355
  // psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id)
194
- static const char kPskIdHashLabel[] = "psk_id_hash";
356
+ // TODO(davidben): Precompute this value and store it with the EVP_HPKE_KDF.
357
+ const EVP_MD *hkdf_md = ctx->kdf->hkdf_md_func();
195
358
  uint8_t psk_id_hash[EVP_MAX_MD_SIZE];
196
359
  size_t psk_id_hash_len;
197
- if (!hpke_labeled_extract(hpke->hkdf_md, psk_id_hash, &psk_id_hash_len, NULL,
198
- 0, suite_id, sizeof(suite_id), kPskIdHashLabel,
199
- psk_id, psk_id_len)) {
360
+ if (!hpke_labeled_extract(hkdf_md, psk_id_hash, &psk_id_hash_len, NULL, 0,
361
+ suite_id, sizeof(suite_id), "psk_id_hash", NULL,
362
+ 0)) {
200
363
  return 0;
201
364
  }
202
365
 
203
366
  // info_hash = LabeledExtract("", "info_hash", info)
204
- static const char kInfoHashLabel[] = "info_hash";
205
367
  uint8_t info_hash[EVP_MAX_MD_SIZE];
206
368
  size_t info_hash_len;
207
- if (!hpke_labeled_extract(hpke->hkdf_md, info_hash, &info_hash_len, NULL, 0,
208
- suite_id, sizeof(suite_id), kInfoHashLabel, info,
369
+ if (!hpke_labeled_extract(hkdf_md, info_hash, &info_hash_len, NULL, 0,
370
+ suite_id, sizeof(suite_id), "info_hash", info,
209
371
  info_len)) {
210
372
  return 0;
211
373
  }
@@ -215,7 +377,7 @@ static int hpke_key_schedule(EVP_HPKE_CTX *hpke, uint8_t mode,
215
377
  size_t context_len;
216
378
  CBB context_cbb;
217
379
  if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) ||
218
- !CBB_add_u8(&context_cbb, mode) ||
380
+ !CBB_add_u8(&context_cbb, HPKE_MODE_BASE) ||
219
381
  !CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) ||
220
382
  !CBB_add_bytes(&context_cbb, info_hash, info_hash_len) ||
221
383
  !CBB_finish(&context_cbb, NULL, &context_len)) {
@@ -223,97 +385,44 @@ static int hpke_key_schedule(EVP_HPKE_CTX *hpke, uint8_t mode,
223
385
  }
224
386
 
225
387
  // secret = LabeledExtract(shared_secret, "secret", psk)
226
- static const char kSecretExtractLabel[] = "secret";
227
388
  uint8_t secret[EVP_MAX_MD_SIZE];
228
389
  size_t secret_len;
229
- if (!hpke_labeled_extract(hpke->hkdf_md, secret, &secret_len, shared_secret,
390
+ if (!hpke_labeled_extract(hkdf_md, secret, &secret_len, shared_secret,
230
391
  shared_secret_len, suite_id, sizeof(suite_id),
231
- kSecretExtractLabel, psk, psk_len)) {
392
+ "secret", NULL, 0)) {
232
393
  return 0;
233
394
  }
234
395
 
235
396
  // key = LabeledExpand(secret, "key", key_schedule_context, Nk)
236
- static const char kKeyExpandLabel[] = "key";
397
+ const EVP_AEAD *aead = EVP_HPKE_AEAD_aead(ctx->aead);
237
398
  uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
238
399
  const size_t kKeyLen = EVP_AEAD_key_length(aead);
239
- if (!hpke_labeled_expand(hpke->hkdf_md, key, kKeyLen, secret, secret_len,
240
- suite_id, sizeof(suite_id), kKeyExpandLabel, context,
241
- context_len)) {
242
- return 0;
243
- }
244
-
245
- // Initialize the HPKE context's AEAD context, storing a copy of |key|.
246
- if (!EVP_AEAD_CTX_init(&hpke->aead_ctx, aead, key, kKeyLen, 0, NULL)) {
400
+ if (!hpke_labeled_expand(hkdf_md, key, kKeyLen, secret, secret_len, suite_id,
401
+ sizeof(suite_id), "key", context, context_len) ||
402
+ !EVP_AEAD_CTX_init(&ctx->aead_ctx, aead, key, kKeyLen,
403
+ EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) {
247
404
  return 0;
248
405
  }
249
406
 
250
407
  // base_nonce = LabeledExpand(secret, "base_nonce", key_schedule_context, Nn)
251
- static const char kNonceExpandLabel[] = "base_nonce";
252
- if (!hpke_labeled_expand(hpke->hkdf_md, hpke->base_nonce,
408
+ if (!hpke_labeled_expand(hkdf_md, ctx->base_nonce,
253
409
  EVP_AEAD_nonce_length(aead), secret, secret_len,
254
- suite_id, sizeof(suite_id), kNonceExpandLabel,
255
- context, context_len)) {
410
+ suite_id, sizeof(suite_id), "base_nonce", context,
411
+ context_len)) {
256
412
  return 0;
257
413
  }
258
414
 
259
415
  // exporter_secret = LabeledExpand(secret, "exp", key_schedule_context, Nh)
260
- static const char kExporterSecretExpandLabel[] = "exp";
261
- if (!hpke_labeled_expand(hpke->hkdf_md, hpke->exporter_secret,
262
- EVP_MD_size(hpke->hkdf_md), secret, secret_len,
263
- suite_id, sizeof(suite_id),
264
- kExporterSecretExpandLabel, context, context_len)) {
416
+ if (!hpke_labeled_expand(hkdf_md, ctx->exporter_secret, EVP_MD_size(hkdf_md),
417
+ secret, secret_len, suite_id, sizeof(suite_id),
418
+ "exp", context, context_len)) {
265
419
  return 0;
266
420
  }
267
421
 
268
422
  return 1;
269
423
  }
270
424
 
271
- // The number of bytes written to |out_shared_secret| is the size of the KEM's
272
- // KDF (currently we only support SHA256).
273
- static int hpke_encap(EVP_HPKE_CTX *hpke,
274
- uint8_t out_shared_secret[SHA256_DIGEST_LENGTH],
275
- const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
276
- const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
277
- const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
278
- uint8_t dh[X25519_PUBLIC_VALUE_LEN];
279
- if (!X25519(dh, ephemeral_private, public_key_r)) {
280
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
281
- return 0;
282
- }
283
-
284
- uint8_t kem_context[KEM_CONTEXT_LEN];
285
- OPENSSL_memcpy(kem_context, ephemeral_public, X25519_PUBLIC_VALUE_LEN);
286
- OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
287
- X25519_PUBLIC_VALUE_LEN);
288
- if (!hpke_extract_and_expand(EVP_sha256(), out_shared_secret,
289
- SHA256_DIGEST_LENGTH, dh, kem_context)) {
290
- return 0;
291
- }
292
- return 1;
293
- }
294
-
295
- static int hpke_decap(const EVP_HPKE_CTX *hpke,
296
- uint8_t out_shared_secret[SHA256_DIGEST_LENGTH],
297
- const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
298
- const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
299
- const uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN]) {
300
- uint8_t dh[X25519_PUBLIC_VALUE_LEN];
301
- if (!X25519(dh, secret_key_r, enc)) {
302
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
303
- return 0;
304
- }
305
- uint8_t kem_context[KEM_CONTEXT_LEN];
306
- OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN);
307
- OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
308
- X25519_PUBLIC_VALUE_LEN);
309
- if (!hpke_extract_and_expand(EVP_sha256(), out_shared_secret,
310
- SHA256_DIGEST_LENGTH, dh, kem_context)) {
311
- return 0;
312
- }
313
- return 1;
314
- }
315
-
316
- void EVP_HPKE_CTX_init(EVP_HPKE_CTX *ctx) {
425
+ void EVP_HPKE_CTX_zero(EVP_HPKE_CTX *ctx) {
317
426
  OPENSSL_memset(ctx, 0, sizeof(EVP_HPKE_CTX));
318
427
  EVP_AEAD_CTX_zero(&ctx->aead_ctx);
319
428
  }
@@ -322,272 +431,154 @@ void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) {
322
431
  EVP_AEAD_CTX_cleanup(&ctx->aead_ctx);
323
432
  }
324
433
 
325
- int EVP_HPKE_CTX_setup_base_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
326
- size_t out_enc_len, uint16_t kdf_id,
327
- uint16_t aead_id,
328
- const uint8_t *peer_public_value,
329
- size_t peer_public_value_len,
330
- const uint8_t *info, size_t info_len) {
331
- if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
332
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
333
- return 0;
334
- }
335
-
336
- // The GenerateKeyPair() step technically belongs in the KEM's Encap()
337
- // function, but we've moved it up a layer to make it easier for tests to
338
- // inject an ephemeral keypair.
339
- uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
340
- X25519_keypair(out_enc, ephemeral_private);
341
- return EVP_HPKE_CTX_setup_base_s_x25519_for_test(
342
- hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
343
- info_len, ephemeral_private, sizeof(ephemeral_private), out_enc,
344
- out_enc_len);
345
- }
346
-
347
- int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
348
- EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
349
- const uint8_t *peer_public_value, size_t peer_public_value_len,
350
- const uint8_t *info, size_t info_len, const uint8_t *ephemeral_private,
351
- size_t ephemeral_private_len, const uint8_t *ephemeral_public,
352
- size_t ephemeral_public_len) {
353
- if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
354
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
355
- return 0;
356
- }
357
- if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
358
- ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
359
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
360
- return 0;
361
- }
362
-
363
- hpke->is_sender = 1;
364
- hpke->kdf_id = kdf_id;
365
- hpke->aead_id = aead_id;
366
- hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
367
- if (hpke->hkdf_md == NULL) {
368
- return 0;
369
- }
370
- uint8_t shared_secret[SHA256_DIGEST_LENGTH];
371
- if (!hpke_encap(hpke, shared_secret, peer_public_value, ephemeral_private,
372
- ephemeral_public) ||
373
- !hpke_key_schedule(hpke, HPKE_MODE_BASE, shared_secret,
374
- sizeof(shared_secret), info, info_len, NULL, 0, NULL,
375
- 0)) {
376
- return 0;
377
- }
378
- return 1;
379
- }
380
-
381
- int EVP_HPKE_CTX_setup_base_r_x25519(EVP_HPKE_CTX *hpke, uint16_t kdf_id,
382
- uint16_t aead_id, const uint8_t *enc,
383
- size_t enc_len, const uint8_t *public_key,
384
- size_t public_key_len,
385
- const uint8_t *private_key,
386
- size_t private_key_len,
387
- const uint8_t *info, size_t info_len) {
388
- if (enc_len != X25519_PUBLIC_VALUE_LEN) {
389
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
390
- return 0;
391
- }
392
- if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
393
- private_key_len != X25519_PRIVATE_KEY_LEN) {
394
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
395
- return 0;
396
- }
397
-
398
- hpke->is_sender = 0;
399
- hpke->kdf_id = kdf_id;
400
- hpke->aead_id = aead_id;
401
- hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
402
- if (hpke->hkdf_md == NULL) {
403
- return 0;
404
- }
405
- uint8_t shared_secret[SHA256_DIGEST_LENGTH];
406
- if (!hpke_decap(hpke, shared_secret, enc, public_key, private_key) ||
407
- !hpke_key_schedule(hpke, HPKE_MODE_BASE, shared_secret,
408
- sizeof(shared_secret), info, info_len, NULL, 0, NULL,
409
- 0)) {
410
- return 0;
411
- }
412
- return 1;
434
+ int EVP_HPKE_CTX_setup_sender(EVP_HPKE_CTX *ctx, uint8_t *out_enc,
435
+ size_t *out_enc_len, size_t max_enc,
436
+ const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf,
437
+ const EVP_HPKE_AEAD *aead,
438
+ const uint8_t *peer_public_key,
439
+ size_t peer_public_key_len, const uint8_t *info,
440
+ size_t info_len) {
441
+ uint8_t seed[MAX_SEED_LEN];
442
+ RAND_bytes(seed, kem->seed_len);
443
+ return EVP_HPKE_CTX_setup_sender_with_seed_for_testing(
444
+ ctx, out_enc, out_enc_len, max_enc, kem, kdf, aead, peer_public_key,
445
+ peer_public_key_len, info, info_len, seed, kem->seed_len);
413
446
  }
414
447
 
415
- int EVP_HPKE_CTX_setup_psk_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
416
- size_t out_enc_len, uint16_t kdf_id,
417
- uint16_t aead_id,
418
- const uint8_t *peer_public_value,
419
- size_t peer_public_value_len,
420
- const uint8_t *info, size_t info_len,
421
- const uint8_t *psk, size_t psk_len,
422
- const uint8_t *psk_id, size_t psk_id_len) {
423
- if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
424
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
425
- return 0;
426
- }
427
-
428
- // The GenerateKeyPair() step technically belongs in the KEM's Encap()
429
- // function, but we've moved it up a layer to make it easier for tests to
430
- // inject an ephemeral keypair.
431
- uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
432
- X25519_keypair(out_enc, ephemeral_private);
433
- return EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
434
- hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
435
- info_len, psk, psk_len, psk_id, psk_id_len, ephemeral_private,
436
- sizeof(ephemeral_private), out_enc, out_enc_len);
437
- }
438
-
439
- int EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
440
- EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
441
- const uint8_t *peer_public_value, size_t peer_public_value_len,
442
- const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
443
- const uint8_t *psk_id, size_t psk_id_len, const uint8_t *ephemeral_private,
444
- size_t ephemeral_private_len, const uint8_t *ephemeral_public,
445
- size_t ephemeral_public_len) {
446
- if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
447
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
448
- return 0;
449
- }
450
- if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
451
- ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
452
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
453
- return 0;
454
- }
455
-
456
- hpke->is_sender = 1;
457
- hpke->kdf_id = kdf_id;
458
- hpke->aead_id = aead_id;
459
- hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
460
- if (hpke->hkdf_md == NULL) {
461
- return 0;
462
- }
463
- uint8_t shared_secret[SHA256_DIGEST_LENGTH];
464
- if (!hpke_encap(hpke, shared_secret, peer_public_value, ephemeral_private,
465
- ephemeral_public) ||
466
- !hpke_key_schedule(hpke, HPKE_MODE_PSK, shared_secret,
467
- sizeof(shared_secret), info, info_len, psk, psk_len,
468
- psk_id, psk_id_len)) {
448
+ int EVP_HPKE_CTX_setup_sender_with_seed_for_testing(
449
+ EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc,
450
+ const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead,
451
+ const uint8_t *peer_public_key, size_t peer_public_key_len,
452
+ const uint8_t *info, size_t info_len, const uint8_t *seed,
453
+ size_t seed_len) {
454
+ EVP_HPKE_CTX_zero(ctx);
455
+ ctx->is_sender = 1;
456
+ ctx->kdf = kdf;
457
+ ctx->aead = aead;
458
+ uint8_t shared_secret[MAX_SHARED_SECRET_LEN];
459
+ size_t shared_secret_len;
460
+ if (!kem->encap_with_seed(kem, shared_secret, &shared_secret_len, out_enc,
461
+ out_enc_len, max_enc, peer_public_key,
462
+ peer_public_key_len, seed, seed_len) ||
463
+ !hpke_key_schedule(ctx, shared_secret, shared_secret_len, info,
464
+ info_len)) {
465
+ EVP_HPKE_CTX_cleanup(ctx);
469
466
  return 0;
470
467
  }
471
468
  return 1;
472
469
  }
473
470
 
474
- int EVP_HPKE_CTX_setup_psk_r_x25519(
475
- EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id, const uint8_t *enc,
476
- size_t enc_len, const uint8_t *public_key, size_t public_key_len,
477
- const uint8_t *private_key, size_t private_key_len, const uint8_t *info,
478
- size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id,
479
- size_t psk_id_len) {
480
- if (enc_len != X25519_PUBLIC_VALUE_LEN) {
481
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
482
- return 0;
483
- }
484
- if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
485
- private_key_len != X25519_PRIVATE_KEY_LEN) {
486
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
487
- return 0;
488
- }
489
-
490
- hpke->is_sender = 0;
491
- hpke->kdf_id = kdf_id;
492
- hpke->aead_id = aead_id;
493
- hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
494
- if (hpke->hkdf_md == NULL) {
495
- return 0;
496
- }
497
- uint8_t shared_secret[SHA256_DIGEST_LENGTH];
498
- if (!hpke_decap(hpke, shared_secret, enc, public_key, private_key) ||
499
- !hpke_key_schedule(hpke, HPKE_MODE_PSK, shared_secret,
500
- sizeof(shared_secret), info, info_len, psk, psk_len,
501
- psk_id, psk_id_len)) {
471
+ int EVP_HPKE_CTX_setup_recipient(EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key,
472
+ const EVP_HPKE_KDF *kdf,
473
+ const EVP_HPKE_AEAD *aead, const uint8_t *enc,
474
+ size_t enc_len, const uint8_t *info,
475
+ size_t info_len) {
476
+ EVP_HPKE_CTX_zero(ctx);
477
+ ctx->is_sender = 0;
478
+ ctx->kdf = kdf;
479
+ ctx->aead = aead;
480
+ uint8_t shared_secret[MAX_SHARED_SECRET_LEN];
481
+ size_t shared_secret_len;
482
+ if (!key->kem->decap(key, shared_secret, &shared_secret_len, enc, enc_len) ||
483
+ !hpke_key_schedule(ctx, shared_secret, sizeof(shared_secret), info,
484
+ info_len)) {
485
+ EVP_HPKE_CTX_cleanup(ctx);
502
486
  return 0;
503
487
  }
504
488
  return 1;
505
489
  }
506
490
 
507
- static void hpke_nonce(const EVP_HPKE_CTX *hpke, uint8_t *out_nonce,
491
+ static void hpke_nonce(const EVP_HPKE_CTX *ctx, uint8_t *out_nonce,
508
492
  size_t nonce_len) {
509
493
  assert(nonce_len >= 8);
510
494
 
511
- // Write padded big-endian bytes of |hpke->seq| to |out_nonce|.
495
+ // Write padded big-endian bytes of |ctx->seq| to |out_nonce|.
512
496
  OPENSSL_memset(out_nonce, 0, nonce_len);
513
- uint64_t seq_copy = hpke->seq;
497
+ uint64_t seq_copy = ctx->seq;
514
498
  for (size_t i = 0; i < 8; i++) {
515
499
  out_nonce[nonce_len - i - 1] = seq_copy & 0xff;
516
500
  seq_copy >>= 8;
517
501
  }
518
502
 
519
- // XOR the encoded sequence with the |hpke->base_nonce|.
503
+ // XOR the encoded sequence with the |ctx->base_nonce|.
520
504
  for (size_t i = 0; i < nonce_len; i++) {
521
- out_nonce[i] ^= hpke->base_nonce[i];
505
+ out_nonce[i] ^= ctx->base_nonce[i];
522
506
  }
523
507
  }
524
508
 
525
- size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *hpke) {
526
- assert(hpke->is_sender);
527
- return EVP_AEAD_max_overhead(hpke->aead_ctx.aead);
528
- }
529
-
530
- int EVP_HPKE_CTX_open(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
509
+ int EVP_HPKE_CTX_open(EVP_HPKE_CTX *ctx, uint8_t *out, size_t *out_len,
531
510
  size_t max_out_len, const uint8_t *in, size_t in_len,
532
511
  const uint8_t *ad, size_t ad_len) {
533
- if (hpke->is_sender) {
512
+ if (ctx->is_sender) {
534
513
  OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
535
514
  return 0;
536
515
  }
537
- if (hpke->seq == UINT64_MAX) {
516
+ if (ctx->seq == UINT64_MAX) {
538
517
  OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
539
518
  return 0;
540
519
  }
541
520
 
542
521
  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
543
- const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
544
- hpke_nonce(hpke, nonce, nonce_len);
522
+ const size_t nonce_len = EVP_AEAD_nonce_length(ctx->aead_ctx.aead);
523
+ hpke_nonce(ctx, nonce, nonce_len);
545
524
 
546
- if (!EVP_AEAD_CTX_open(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
525
+ if (!EVP_AEAD_CTX_open(&ctx->aead_ctx, out, out_len, max_out_len, nonce,
547
526
  nonce_len, in, in_len, ad, ad_len)) {
548
527
  return 0;
549
528
  }
550
- hpke->seq++;
529
+ ctx->seq++;
551
530
  return 1;
552
531
  }
553
532
 
554
- int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
533
+ int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *ctx, uint8_t *out, size_t *out_len,
555
534
  size_t max_out_len, const uint8_t *in, size_t in_len,
556
535
  const uint8_t *ad, size_t ad_len) {
557
- if (!hpke->is_sender) {
536
+ if (!ctx->is_sender) {
558
537
  OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
559
538
  return 0;
560
539
  }
561
- if (hpke->seq == UINT64_MAX) {
540
+ if (ctx->seq == UINT64_MAX) {
562
541
  OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
563
542
  return 0;
564
543
  }
565
544
 
566
545
  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
567
- const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
568
- hpke_nonce(hpke, nonce, nonce_len);
546
+ const size_t nonce_len = EVP_AEAD_nonce_length(ctx->aead_ctx.aead);
547
+ hpke_nonce(ctx, nonce, nonce_len);
569
548
 
570
- if (!EVP_AEAD_CTX_seal(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
549
+ if (!EVP_AEAD_CTX_seal(&ctx->aead_ctx, out, out_len, max_out_len, nonce,
571
550
  nonce_len, in, in_len, ad, ad_len)) {
572
551
  return 0;
573
552
  }
574
- hpke->seq++;
553
+ ctx->seq++;
575
554
  return 1;
576
555
  }
577
556
 
578
- int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *hpke, uint8_t *out,
557
+ int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *ctx, uint8_t *out,
579
558
  size_t secret_len, const uint8_t *context,
580
559
  size_t context_len) {
581
560
  uint8_t suite_id[HPKE_SUITE_ID_LEN];
582
- if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
561
+ if (!hpke_build_suite_id(ctx, suite_id)) {
583
562
  return 0;
584
563
  }
585
- static const char kExportExpandLabel[] = "sec";
586
- if (!hpke_labeled_expand(hpke->hkdf_md, out, secret_len,
587
- hpke->exporter_secret, EVP_MD_size(hpke->hkdf_md),
588
- suite_id, sizeof(suite_id), kExportExpandLabel,
589
- context, context_len)) {
564
+ const EVP_MD *hkdf_md = ctx->kdf->hkdf_md_func();
565
+ if (!hpke_labeled_expand(hkdf_md, out, secret_len, ctx->exporter_secret,
566
+ EVP_MD_size(hkdf_md), suite_id, sizeof(suite_id),
567
+ "sec", context, context_len)) {
590
568
  return 0;
591
569
  }
592
570
  return 1;
593
571
  }
572
+
573
+ size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *ctx) {
574
+ assert(ctx->is_sender);
575
+ return EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(&ctx->aead_ctx));
576
+ }
577
+
578
+ const EVP_HPKE_AEAD *EVP_HPKE_CTX_aead(const EVP_HPKE_CTX *ctx) {
579
+ return ctx->aead;
580
+ }
581
+
582
+ const EVP_HPKE_KDF *EVP_HPKE_CTX_kdf(const EVP_HPKE_CTX *ctx) {
583
+ return ctx->kdf;
584
+ }