Skip to content

Commit 3b16449

Browse files
authored
refactor: remove unused prf hmac impls (#5148)
1 parent 5479708 commit 3b16449

File tree

5 files changed

+19
-211
lines changed

5 files changed

+19
-211
lines changed

crypto/s2n_evp.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@ struct s2n_evp_digest {
2626
EVP_MD_CTX *ctx;
2727
};
2828

29-
struct s2n_evp_hmac_state {
30-
struct s2n_evp_digest evp_digest;
31-
union {
32-
HMAC_CTX *hmac_ctx;
33-
EVP_PKEY *evp_pkey;
34-
} ctx;
35-
};
36-
3729
/* Define API's that change based on the OpenSSL Major Version. */
3830
#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
3931
#define S2N_EVP_MD_CTX_NEW() (EVP_MD_CTX_new())

tests/cbmc/include/cbmc_proof/make_common_datastructures.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,6 @@ void cbmc_populate_s2n_evp_digest(struct s2n_evp_digest *evp_digest);
197197
*/
198198
struct s2n_evp_digest* cbmc_allocate_s2n_evp_digest();
199199

200-
/*
201-
* Populates the fields of a pre-allocated s2n_evp_digest for CBMC proofs.
202-
*/
203-
void cbmc_populate_s2n_evp_hmac_state(struct s2n_evp_hmac_state *evp_hmac_state);
204-
205-
/*
206-
* Properly allocates s2n_evp_hmac_state for CBMC proofs.
207-
*/
208-
struct s2n_evp_hmac_state *cbmc_allocate_s2n_evp_hmac_state();
209-
210200
/*
211201
* Populates the fields of a pre-allocated s2n_hash_state for CBMC proofs.
212202
*/

tests/cbmc/sources/make_common_datastructures.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -244,24 +244,6 @@ struct s2n_evp_digest* cbmc_allocate_s2n_evp_digest()
244244
return evp_digest;
245245
}
246246

247-
void cbmc_populate_s2n_evp_hmac_state(struct s2n_evp_hmac_state *evp_hmac_state)
248-
{
249-
CBMC_ENSURE_REF(evp_hmac_state);
250-
cbmc_populate_s2n_evp_digest(&(evp_hmac_state->evp_digest));
251-
if (s2n_libcrypto_is_awslc() || s2n_libcrypto_is_boringssl()) {
252-
evp_hmac_state->ctx.hmac_ctx = malloc(sizeof(*(evp_hmac_state->ctx.hmac_ctx)));
253-
} else {
254-
evp_hmac_state->ctx.evp_pkey = malloc(sizeof(*(evp_hmac_state->ctx.evp_pkey)));
255-
}
256-
}
257-
258-
struct s2n_evp_hmac_state *cbmc_allocate_s2n_evp_hmac_state()
259-
{
260-
struct s2n_evp_hmac_state *evp_hmac_state = malloc(sizeof(*evp_hmac_state));
261-
cbmc_populate_s2n_evp_hmac_state(evp_hmac_state);
262-
return evp_hmac_state;
263-
}
264-
265247
void cbmc_populate_s2n_hash_state(struct s2n_hash_state* state)
266248
{
267249
CBMC_ENSURE_REF(state);
@@ -715,7 +697,6 @@ void cbmc_populate_s2n_prf_working_space(struct s2n_prf_working_space *s2n_prf_w
715697
* If required, this initialization should be done in the validation function.
716698
*/
717699
cbmc_populate_s2n_hmac_state(&(s2n_prf_working_space->p_hash.s2n_hmac));
718-
cbmc_populate_s2n_evp_hmac_state(&(s2n_prf_working_space->p_hash.evp_hmac));
719700
}
720701

721702
struct s2n_prf_working_space* cbmc_allocate_s2n_prf_working_space()

tls/s2n_prf.c

Lines changed: 19 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@
4040
#define S2N_LIBCRYPTO_SUPPORTS_TLS_PRF 0
4141
#endif
4242

43-
/* The s2n p_hash implementation is abstracted to allow for separate implementations, using
44-
* either s2n's formally verified HMAC or OpenSSL's EVP HMAC, for use by the TLS PRF. */
43+
/* The s2n p_hash implementation is abstracted to allow for separate implementations.
44+
* Currently the only implementation uses s2n-tls's custom HMAC implementation.
45+
*/
4546
struct s2n_p_hash_hmac {
4647
int (*alloc)(struct s2n_prf_working_space *ws);
4748
int (*init)(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret);
@@ -194,175 +195,9 @@ static int s2n_prf_sslv3(struct s2n_connection *conn, struct s2n_blob *secret, s
194195
return 0;
195196
}
196197

197-
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
198-
static int s2n_evp_pkey_p_hash_alloc(struct s2n_prf_working_space *ws)
199-
{
200-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.evp_digest.ctx = S2N_EVP_MD_CTX_NEW());
201-
return 0;
202-
}
203-
204-
static int s2n_evp_pkey_p_hash_digest_init(struct s2n_prf_working_space *ws)
205-
{
206-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.evp_digest.md);
207-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.evp_digest.ctx);
208-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.ctx.evp_pkey);
209-
210-
POSIX_GUARD_OSSL(EVP_DigestSignInit(ws->p_hash.evp_hmac.evp_digest.ctx, NULL, ws->p_hash.evp_hmac.evp_digest.md, NULL, ws->p_hash.evp_hmac.ctx.evp_pkey),
211-
S2N_ERR_P_HASH_INIT_FAILED);
212-
213-
return 0;
214-
}
215-
216-
static int s2n_evp_pkey_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
217-
{
218-
/* Initialize the message digest */
219-
POSIX_GUARD_RESULT(s2n_hmac_md_from_alg(alg, &ws->p_hash.evp_hmac.evp_digest.md));
220-
221-
/* Initialize the mac key using the provided secret */
222-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.ctx.evp_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));
223-
224-
/* Initialize the message digest context with the above message digest and mac key */
225-
return s2n_evp_pkey_p_hash_digest_init(ws);
226-
}
227-
228-
static int s2n_evp_pkey_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
229-
{
230-
POSIX_GUARD_OSSL(EVP_DigestSignUpdate(ws->p_hash.evp_hmac.evp_digest.ctx, data, (size_t) size), S2N_ERR_P_HASH_UPDATE_FAILED);
231-
232-
return 0;
233-
}
234-
235-
static int s2n_evp_pkey_p_hash_final(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
236-
{
237-
/* EVP_DigestSign API's require size_t data structures */
238-
size_t digest_size = size;
239-
240-
POSIX_GUARD_OSSL(EVP_DigestSignFinal(ws->p_hash.evp_hmac.evp_digest.ctx, (unsigned char *) digest, &digest_size), S2N_ERR_P_HASH_FINAL_FAILED);
241-
242-
return 0;
243-
}
244-
245-
static int s2n_evp_pkey_p_hash_wipe(struct s2n_prf_working_space *ws)
246-
{
247-
POSIX_GUARD_OSSL(S2N_EVP_MD_CTX_RESET(ws->p_hash.evp_hmac.evp_digest.ctx), S2N_ERR_P_HASH_WIPE_FAILED);
248-
249-
return 0;
250-
}
251-
252-
static int s2n_evp_pkey_p_hash_reset(struct s2n_prf_working_space *ws)
253-
{
254-
POSIX_GUARD(s2n_evp_pkey_p_hash_wipe(ws));
255-
256-
/*
257-
* On some cleanup paths s2n_evp_pkey_p_hash_reset can be called before s2n_evp_pkey_p_hash_init so there is nothing
258-
* to reset.
259-
*/
260-
if (ws->p_hash.evp_hmac.ctx.evp_pkey == NULL) {
261-
return S2N_SUCCESS;
262-
}
263-
return s2n_evp_pkey_p_hash_digest_init(ws);
264-
}
265-
266-
static int s2n_evp_pkey_p_hash_cleanup(struct s2n_prf_working_space *ws)
267-
{
268-
/* Prepare the workspace md_ctx for the next p_hash */
269-
POSIX_GUARD(s2n_evp_pkey_p_hash_wipe(ws));
270-
271-
/* Free mac key - PKEYs cannot be reused */
272-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.ctx.evp_pkey);
273-
EVP_PKEY_free(ws->p_hash.evp_hmac.ctx.evp_pkey);
274-
ws->p_hash.evp_hmac.ctx.evp_pkey = NULL;
275-
276-
return 0;
277-
}
278-
279-
static int s2n_evp_pkey_p_hash_free(struct s2n_prf_working_space *ws)
280-
{
281-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.evp_digest.ctx);
282-
S2N_EVP_MD_CTX_FREE(ws->p_hash.evp_hmac.evp_digest.ctx);
283-
ws->p_hash.evp_hmac.evp_digest.ctx = NULL;
284-
285-
return 0;
286-
}
287-
288-
static const struct s2n_p_hash_hmac s2n_evp_pkey_p_hash_hmac = {
289-
.alloc = &s2n_evp_pkey_p_hash_alloc,
290-
.init = &s2n_evp_pkey_p_hash_init,
291-
.update = &s2n_evp_pkey_p_hash_update,
292-
.final = &s2n_evp_pkey_p_hash_final,
293-
.reset = &s2n_evp_pkey_p_hash_reset,
294-
.cleanup = &s2n_evp_pkey_p_hash_cleanup,
295-
.free = &s2n_evp_pkey_p_hash_free,
296-
};
297-
#else
298-
static int s2n_evp_hmac_p_hash_alloc(struct s2n_prf_working_space *ws)
299-
{
300-
POSIX_ENSURE_REF(ws->p_hash.evp_hmac.ctx.hmac_ctx = HMAC_CTX_new());
301-
return S2N_SUCCESS;
302-
}
303-
304-
static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
305-
{
306-
/* Figure out the correct EVP_MD from s2n_hmac_algorithm */
307-
POSIX_GUARD_RESULT(s2n_hmac_md_from_alg(alg, &ws->p_hash.evp_hmac.evp_digest.md));
308-
309-
/* Initialize the mac and digest */
310-
POSIX_GUARD_OSSL(HMAC_Init_ex(ws->p_hash.evp_hmac.ctx.hmac_ctx, secret->data, secret->size, ws->p_hash.evp_hmac.evp_digest.md, NULL), S2N_ERR_P_HASH_INIT_FAILED);
311-
return S2N_SUCCESS;
312-
}
313-
314-
static int s2n_evp_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
315-
{
316-
POSIX_GUARD_OSSL(HMAC_Update(ws->p_hash.evp_hmac.ctx.hmac_ctx, data, (size_t) size), S2N_ERR_P_HASH_UPDATE_FAILED);
317-
return S2N_SUCCESS;
318-
}
319-
320-
static int s2n_evp_hmac_p_hash_final(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
321-
{
322-
/* HMAC_Final API's require size_t data structures */
323-
unsigned int digest_size = size;
324-
POSIX_GUARD_OSSL(HMAC_Final(ws->p_hash.evp_hmac.ctx.hmac_ctx, (unsigned char *) digest, &digest_size), S2N_ERR_P_HASH_FINAL_FAILED);
325-
return S2N_SUCCESS;
326-
}
327-
328-
static int s2n_evp_hmac_p_hash_reset(struct s2n_prf_working_space *ws)
329-
{
330-
POSIX_ENSURE_REF(ws);
331-
if (ws->p_hash.evp_hmac.evp_digest.md == NULL) {
332-
return S2N_SUCCESS;
333-
}
334-
POSIX_GUARD_OSSL(HMAC_Init_ex(ws->p_hash.evp_hmac.ctx.hmac_ctx, NULL, 0, ws->p_hash.evp_hmac.evp_digest.md, NULL), S2N_ERR_P_HASH_INIT_FAILED);
335-
return S2N_SUCCESS;
336-
}
337-
338-
static int s2n_evp_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
339-
{
340-
/* Prepare the workspace md_ctx for the next p_hash */
341-
HMAC_CTX_reset(ws->p_hash.evp_hmac.ctx.hmac_ctx);
342-
return S2N_SUCCESS;
343-
}
344-
345-
static int s2n_evp_hmac_p_hash_free(struct s2n_prf_working_space *ws)
346-
{
347-
HMAC_CTX_free(ws->p_hash.evp_hmac.ctx.hmac_ctx);
348-
return S2N_SUCCESS;
349-
}
350-
351-
static const struct s2n_p_hash_hmac s2n_evp_hmac_p_hash_hmac = {
352-
.alloc = &s2n_evp_hmac_p_hash_alloc,
353-
.init = &s2n_evp_hmac_p_hash_init,
354-
.update = &s2n_evp_hmac_p_hash_update,
355-
.final = &s2n_evp_hmac_p_hash_final,
356-
.reset = &s2n_evp_hmac_p_hash_reset,
357-
.cleanup = &s2n_evp_hmac_p_hash_cleanup,
358-
.free = &s2n_evp_hmac_p_hash_free,
359-
};
360-
#endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) */
361-
362198
static int s2n_hmac_p_hash_new(struct s2n_prf_working_space *ws)
363199
{
364200
POSIX_GUARD(s2n_hmac_new(&ws->p_hash.s2n_hmac));
365-
366201
return s2n_hmac_init(&ws->p_hash.s2n_hmac, S2N_HMAC_NONE, NULL, 0);
367202
}
368203

@@ -412,13 +247,20 @@ static const struct s2n_p_hash_hmac s2n_internal_p_hash_hmac = {
412247
.free = &s2n_hmac_p_hash_free,
413248
};
414249

250+
/*
251+
* For now, use the internal s2n-tls hmac abstraction.
252+
* However, that is a custom implementation of hmac built on hashes.
253+
* Ideally we should stop using our custom implementation here and switch
254+
* to using a libcrypto implementation. Unfortunately, what each libcrypto
255+
* can support varies a lot for HMACs.
256+
*
257+
* For historical reference, there used to be two other hmac implementations:
258+
* https://github.com/aws/s2n-tls/blob/711ee0df658cd7c44088cf7a1b20a9f3cf5296d6/tls/s2n_prf.c#L174-L337
259+
* Both implementations have compatibility issues with one or more libcryptos.
260+
*/
415261
const struct s2n_p_hash_hmac *s2n_get_hmac_implementation()
416262
{
417-
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
418-
return s2n_is_in_fips_mode() ? &s2n_evp_hmac_p_hash_hmac : &s2n_internal_p_hash_hmac;
419-
#else
420-
return s2n_is_in_fips_mode() ? &s2n_evp_pkey_p_hash_hmac : &s2n_internal_p_hash_hmac;
421-
#endif
263+
return &s2n_internal_p_hash_hmac;
422264
}
423265

424266
static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret, struct s2n_blob *label,
@@ -428,6 +270,7 @@ static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg,
428270
POSIX_GUARD(s2n_hmac_digest_size(alg, &digest_size));
429271

430272
const struct s2n_p_hash_hmac *hmac = s2n_get_hmac_implementation();
273+
POSIX_ENSURE_REF(hmac);
431274

432275
/* First compute hmac(secret + A(0)) */
433276
POSIX_GUARD(hmac->init(ws, alg, secret));
@@ -494,6 +337,7 @@ S2N_RESULT s2n_prf_new(struct s2n_connection *conn)
494337

495338
/* Allocate the hmac state */
496339
const struct s2n_p_hash_hmac *hmac_impl = s2n_get_hmac_implementation();
340+
RESULT_ENSURE_REF(hmac_impl);
497341
RESULT_GUARD_POSIX(hmac_impl->alloc(conn->prf_space));
498342
return S2N_RESULT_OK;
499343
}
@@ -504,6 +348,7 @@ S2N_RESULT s2n_prf_wipe(struct s2n_connection *conn)
504348
RESULT_ENSURE_REF(conn->prf_space);
505349

506350
const struct s2n_p_hash_hmac *hmac_impl = s2n_get_hmac_implementation();
351+
RESULT_ENSURE_REF(hmac_impl);
507352
RESULT_GUARD_POSIX(hmac_impl->reset(conn->prf_space));
508353

509354
return S2N_RESULT_OK;
@@ -517,6 +362,7 @@ S2N_RESULT s2n_prf_free(struct s2n_connection *conn)
517362
}
518363

519364
const struct s2n_p_hash_hmac *hmac_impl = s2n_get_hmac_implementation();
365+
RESULT_ENSURE_REF(hmac_impl);
520366
RESULT_GUARD_POSIX(hmac_impl->free(conn->prf_space));
521367

522368
RESULT_GUARD_POSIX(s2n_free_object((uint8_t **) &conn->prf_space, sizeof(struct s2n_prf_working_space)));

tls/s2n_prf.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
union p_hash_state {
2828
struct s2n_hmac_state s2n_hmac;
29-
struct s2n_evp_hmac_state evp_hmac;
3029
};
3130

3231
struct s2n_prf_working_space {

0 commit comments

Comments
 (0)