1 | /*
|
---|
2 | * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | /* APIs and data structures for HPKE (RFC9180) */
|
---|
11 | #ifndef OSSL_HPKE_H
|
---|
12 | # define OSSL_HPKE_H
|
---|
13 | # pragma once
|
---|
14 |
|
---|
15 | # include <openssl/types.h>
|
---|
16 |
|
---|
17 | /* HPKE modes */
|
---|
18 | # define OSSL_HPKE_MODE_BASE 0 /* Base mode */
|
---|
19 | # define OSSL_HPKE_MODE_PSK 1 /* Pre-shared key mode */
|
---|
20 | # define OSSL_HPKE_MODE_AUTH 2 /* Authenticated mode */
|
---|
21 | # define OSSL_HPKE_MODE_PSKAUTH 3 /* PSK+authenticated mode */
|
---|
22 |
|
---|
23 | /*
|
---|
24 | * Max for ikm, psk, pskid, info and exporter contexts.
|
---|
25 | * RFC9180, section 7.2.1 RECOMMENDS 64 octets but we have test vectors from
|
---|
26 | * Appendix A.6.1 with a 66 octet IKM so we'll allow that.
|
---|
27 | */
|
---|
28 | # define OSSL_HPKE_MAX_PARMLEN 66
|
---|
29 | # define OSSL_HPKE_MIN_PSKLEN 32
|
---|
30 | # define OSSL_HPKE_MAX_INFOLEN 1024
|
---|
31 |
|
---|
32 | /*
|
---|
33 | * The (16bit) HPKE algorithm ID IANA codepoints
|
---|
34 | * If/when new IANA codepoints are added there are tables in
|
---|
35 | * crypto/hpke/hpke_util.c that must also be updated.
|
---|
36 | */
|
---|
37 | # define OSSL_HPKE_KEM_ID_RESERVED 0x0000 /* not used */
|
---|
38 | # define OSSL_HPKE_KEM_ID_P256 0x0010 /* NIST P-256 */
|
---|
39 | # define OSSL_HPKE_KEM_ID_P384 0x0011 /* NIST P-384 */
|
---|
40 | # define OSSL_HPKE_KEM_ID_P521 0x0012 /* NIST P-521 */
|
---|
41 | # define OSSL_HPKE_KEM_ID_X25519 0x0020 /* Curve25519 */
|
---|
42 | # define OSSL_HPKE_KEM_ID_X448 0x0021 /* Curve448 */
|
---|
43 |
|
---|
44 | # define OSSL_HPKE_KDF_ID_RESERVED 0x0000 /* not used */
|
---|
45 | # define OSSL_HPKE_KDF_ID_HKDF_SHA256 0x0001 /* HKDF-SHA256 */
|
---|
46 | # define OSSL_HPKE_KDF_ID_HKDF_SHA384 0x0002 /* HKDF-SHA384 */
|
---|
47 | # define OSSL_HPKE_KDF_ID_HKDF_SHA512 0x0003 /* HKDF-SHA512 */
|
---|
48 |
|
---|
49 | # define OSSL_HPKE_AEAD_ID_RESERVED 0x0000 /* not used */
|
---|
50 | # define OSSL_HPKE_AEAD_ID_AES_GCM_128 0x0001 /* AES-GCM-128 */
|
---|
51 | # define OSSL_HPKE_AEAD_ID_AES_GCM_256 0x0002 /* AES-GCM-256 */
|
---|
52 | # define OSSL_HPKE_AEAD_ID_CHACHA_POLY1305 0x0003 /* Chacha20-Poly1305 */
|
---|
53 | # define OSSL_HPKE_AEAD_ID_EXPORTONLY 0xFFFF /* export-only fake ID */
|
---|
54 |
|
---|
55 | /* strings for suite components */
|
---|
56 | # define OSSL_HPKE_KEMSTR_P256 "P-256" /* KEM id 0x10 */
|
---|
57 | # define OSSL_HPKE_KEMSTR_P384 "P-384" /* KEM id 0x11 */
|
---|
58 | # define OSSL_HPKE_KEMSTR_P521 "P-521" /* KEM id 0x12 */
|
---|
59 | # define OSSL_HPKE_KEMSTR_X25519 "X25519" /* KEM id 0x20 */
|
---|
60 | # define OSSL_HPKE_KEMSTR_X448 "X448" /* KEM id 0x21 */
|
---|
61 | # define OSSL_HPKE_KDFSTR_256 "hkdf-sha256" /* KDF id 1 */
|
---|
62 | # define OSSL_HPKE_KDFSTR_384 "hkdf-sha384" /* KDF id 2 */
|
---|
63 | # define OSSL_HPKE_KDFSTR_512 "hkdf-sha512" /* KDF id 3 */
|
---|
64 | # define OSSL_HPKE_AEADSTR_AES128GCM "aes-128-gcm" /* AEAD id 1 */
|
---|
65 | # define OSSL_HPKE_AEADSTR_AES256GCM "aes-256-gcm" /* AEAD id 2 */
|
---|
66 | # define OSSL_HPKE_AEADSTR_CP "chacha20-poly1305" /* AEAD id 3 */
|
---|
67 | # define OSSL_HPKE_AEADSTR_EXP "exporter" /* AEAD id 0xff */
|
---|
68 |
|
---|
69 | /*
|
---|
70 | * Roles for use in creating an OSSL_HPKE_CTX, most
|
---|
71 | * important use of this is to control nonce reuse.
|
---|
72 | */
|
---|
73 | # define OSSL_HPKE_ROLE_SENDER 0
|
---|
74 | # define OSSL_HPKE_ROLE_RECEIVER 1
|
---|
75 |
|
---|
76 | # ifdef __cplusplus
|
---|
77 | extern "C" {
|
---|
78 | # endif
|
---|
79 |
|
---|
80 | typedef struct {
|
---|
81 | uint16_t kem_id; /* Key Encapsulation Method id */
|
---|
82 | uint16_t kdf_id; /* Key Derivation Function id */
|
---|
83 | uint16_t aead_id; /* AEAD alg id */
|
---|
84 | } OSSL_HPKE_SUITE;
|
---|
85 |
|
---|
86 | /**
|
---|
87 | * Suite constants, use this like:
|
---|
88 | * OSSL_HPKE_SUITE myvar = OSSL_HPKE_SUITE_DEFAULT;
|
---|
89 | */
|
---|
90 | # ifndef OPENSSL_NO_ECX
|
---|
91 | # define OSSL_HPKE_SUITE_DEFAULT \
|
---|
92 | {\
|
---|
93 | OSSL_HPKE_KEM_ID_X25519, \
|
---|
94 | OSSL_HPKE_KDF_ID_HKDF_SHA256, \
|
---|
95 | OSSL_HPKE_AEAD_ID_AES_GCM_128 \
|
---|
96 | }
|
---|
97 | # else
|
---|
98 | # define OSSL_HPKE_SUITE_DEFAULT \
|
---|
99 | {\
|
---|
100 | OSSL_HPKE_KEM_ID_P256, \
|
---|
101 | OSSL_HPKE_KDF_ID_HKDF_SHA256, \
|
---|
102 | OSSL_HPKE_AEAD_ID_AES_GCM_128 \
|
---|
103 | }
|
---|
104 | #endif
|
---|
105 |
|
---|
106 | typedef struct ossl_hpke_ctx_st OSSL_HPKE_CTX;
|
---|
107 |
|
---|
108 | OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role,
|
---|
109 | OSSL_LIB_CTX *libctx, const char *propq);
|
---|
110 | void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx);
|
---|
111 |
|
---|
112 | int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx,
|
---|
113 | unsigned char *enc, size_t *enclen,
|
---|
114 | const unsigned char *pub, size_t publen,
|
---|
115 | const unsigned char *info, size_t infolen);
|
---|
116 | int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx,
|
---|
117 | unsigned char *ct, size_t *ctlen,
|
---|
118 | const unsigned char *aad, size_t aadlen,
|
---|
119 | const unsigned char *pt, size_t ptlen);
|
---|
120 |
|
---|
121 | int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite,
|
---|
122 | unsigned char *pub, size_t *publen, EVP_PKEY **priv,
|
---|
123 | const unsigned char *ikm, size_t ikmlen,
|
---|
124 | OSSL_LIB_CTX *libctx, const char *propq);
|
---|
125 | int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx,
|
---|
126 | const unsigned char *enc, size_t enclen,
|
---|
127 | EVP_PKEY *recippriv,
|
---|
128 | const unsigned char *info, size_t infolen);
|
---|
129 | int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx,
|
---|
130 | unsigned char *pt, size_t *ptlen,
|
---|
131 | const unsigned char *aad, size_t aadlen,
|
---|
132 | const unsigned char *ct, size_t ctlen);
|
---|
133 |
|
---|
134 | int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx,
|
---|
135 | unsigned char *secret,
|
---|
136 | size_t secretlen,
|
---|
137 | const unsigned char *label,
|
---|
138 | size_t labellen);
|
---|
139 |
|
---|
140 | int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv);
|
---|
141 | int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx,
|
---|
142 | const unsigned char *pub,
|
---|
143 | size_t publen);
|
---|
144 | int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx,
|
---|
145 | const char *pskid,
|
---|
146 | const unsigned char *psk, size_t psklen);
|
---|
147 |
|
---|
148 | int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx,
|
---|
149 | const unsigned char *ikme, size_t ikmelen);
|
---|
150 |
|
---|
151 | int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq);
|
---|
152 | int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq);
|
---|
153 |
|
---|
154 | int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite);
|
---|
155 | int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in,
|
---|
156 | OSSL_HPKE_SUITE *suite,
|
---|
157 | unsigned char *enc, size_t *enclen,
|
---|
158 | unsigned char *ct, size_t ctlen,
|
---|
159 | OSSL_LIB_CTX *libctx, const char *propq);
|
---|
160 | int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite);
|
---|
161 | size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen);
|
---|
162 | size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite);
|
---|
163 | size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite);
|
---|
164 |
|
---|
165 | # ifdef __cplusplus
|
---|
166 | }
|
---|
167 | # endif
|
---|
168 |
|
---|
169 | #endif
|
---|