]>
git.ipfire.org Git - thirdparty/openssl.git/blob - ssl/quic/quic_record_shared.c
1 #include "quic_record_shared.h"
2 #include "internal/quic_record_util.h"
3 #include "internal/common.h"
4 #include "../ssl_local.h"
6 /* Constants used for key derivation in QUIC v1. */
7 static const unsigned char quic_v1_iv_label
[] = {
8 0x71, 0x75, 0x69, 0x63, 0x20, 0x69, 0x76 /* "quic iv" */
10 static const unsigned char quic_v1_key_label
[] = {
11 0x71, 0x75, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79 /* "quic key" */
13 static const unsigned char quic_v1_hp_label
[] = {
14 0x71, 0x75, 0x69, 0x63, 0x20, 0x68, 0x70 /* "quic hp" */
17 OSSL_QRL_ENC_LEVEL
*ossl_qrl_enc_level_set_get(OSSL_QRL_ENC_LEVEL_SET
*els
,
21 OSSL_QRL_ENC_LEVEL
*el
;
23 if (!ossl_assert(enc_level
< QUIC_ENC_LEVEL_NUM
))
26 el
= &els
->el
[enc_level
];
28 if (require_valid
&& (el
->cctx
== NULL
|| el
->discarded
))
34 int ossl_qrl_enc_level_set_have_el(OSSL_QRL_ENC_LEVEL_SET
*els
,
37 OSSL_QRL_ENC_LEVEL
*el
= ossl_qrl_enc_level_set_get(els
, enc_level
, 0);
49 * Sets up cryptographic state for a given encryption level and direction by
50 * deriving "quic iv", "quic key" and "quic hp" values from a given secret.
52 * md is a hash function used for key derivation. If it is NULL, this function
53 * fetches the necessary hash function itself. If it is non-NULL, this function
54 * can reuse the caller's reference to a suitable EVP_MD; the EVP_MD provided
55 * must match the suite.
57 * On success where md is non-NULL, takes ownership of the caller's reference to
60 int ossl_qrl_enc_level_set_provide_secret(OSSL_QRL_ENC_LEVEL_SET
*els
,
66 const unsigned char *secret
,
69 OSSL_QRL_ENC_LEVEL
*el
= ossl_qrl_enc_level_set_get(els
, enc_level
, 0);
70 unsigned char key
[EVP_MAX_KEY_LENGTH
], hpr_key
[EVP_MAX_KEY_LENGTH
];
71 size_t key_len
= 0, hpr_key_len
= 0, iv_len
= 0;
72 const char *cipher_name
= NULL
, *md_name
= NULL
;
73 EVP_CIPHER
*cipher
= NULL
;
74 EVP_CIPHER_CTX
*cctx
= NULL
;
75 int own_md
= 0, have_hpr
= 0;
77 if (el
== NULL
|| el
->discarded
)
78 /* Should not be trying to reinitialise an EL which was discarded. */
81 cipher_name
= ossl_qrl_get_suite_cipher_name(suite_id
);
82 iv_len
= ossl_qrl_get_suite_cipher_iv_len(suite_id
);
83 key_len
= ossl_qrl_get_suite_cipher_key_len(suite_id
);
84 hpr_key_len
= ossl_qrl_get_suite_hdr_prot_key_len(suite_id
);
85 if (cipher_name
== NULL
)
88 if (secret_len
!= ossl_qrl_get_suite_secret_len(suite_id
))
92 md_name
= ossl_qrl_get_suite_md_name(suite_id
);
94 if ((md
= EVP_MD_fetch(libctx
, md_name
, propq
)) == NULL
)
100 /* Derive "quic iv" key. */
101 if (!tls13_hkdf_expand_ex(libctx
, propq
,
105 sizeof(quic_v1_iv_label
),
110 /* Derive "quic key" key. */
111 if (!tls13_hkdf_expand_ex(libctx
, propq
,
115 sizeof(quic_v1_key_label
),
120 /* Derive "quic hp" key. */
121 if (!tls13_hkdf_expand_ex(libctx
, propq
,
125 sizeof(quic_v1_hp_label
),
127 hpr_key
, hpr_key_len
, 0))
130 /* Free any old context which is using old keying material. */
131 if (el
->cctx
!= NULL
) {
132 ossl_quic_hdr_protector_destroy(&el
->hpr
);
133 EVP_CIPHER_CTX_free(el
->cctx
);
137 /* Setup header protection context. */
138 if (!ossl_quic_hdr_protector_init(&el
->hpr
,
141 ossl_qrl_get_suite_hdr_prot_cipher_id(suite_id
),
148 /* Create and initialise cipher context. */
149 if ((cipher
= EVP_CIPHER_fetch(libctx
, cipher_name
, propq
)) == NULL
)
152 if (!ossl_assert(iv_len
== (size_t)EVP_CIPHER_get_iv_length(cipher
))
153 || !ossl_assert(key_len
== (size_t)EVP_CIPHER_get_key_length(cipher
)))
156 if ((cctx
= EVP_CIPHER_CTX_new()) == NULL
)
159 /* IV will be changed on RX/TX so we don't need to use a real value here. */
160 if (!EVP_CipherInit_ex(cctx
, cipher
, NULL
, key
, el
->iv
, 0))
163 el
->suite_id
= suite_id
;
166 el
->tag_len
= ossl_qrl_get_suite_cipher_tag_len(suite_id
);
169 /* Zeroize intermediate keys. */
170 OPENSSL_cleanse(key
, sizeof(key
));
171 OPENSSL_cleanse(hpr_key
, sizeof(hpr_key
));
172 EVP_CIPHER_free(cipher
);
177 ossl_quic_hdr_protector_destroy(&el
->hpr
);
178 EVP_CIPHER_CTX_free(cctx
);
179 EVP_CIPHER_free(cipher
);
185 /* Drops keying material for a given encryption level. */
186 void ossl_qrl_enc_level_set_discard(OSSL_QRL_ENC_LEVEL_SET
*els
,
187 uint32_t enc_level
, int is_final
)
189 OSSL_QRL_ENC_LEVEL
*el
= ossl_qrl_enc_level_set_get(els
, enc_level
, 0);
191 if (el
== NULL
|| el
->discarded
)
194 if (el
->cctx
!= NULL
) {
195 ossl_quic_hdr_protector_destroy(&el
->hpr
);
197 EVP_CIPHER_CTX_free(el
->cctx
);
205 OPENSSL_cleanse(el
->iv
, sizeof(el
->iv
));