@@ -171,175 +171,9 @@ static int s2n_sslv3_prf(struct s2n_connection *conn, struct s2n_blob *secret, s
171
171
return 0 ;
172
172
}
173
173
174
- #if !defined(OPENSSL_IS_BORINGSSL ) && !defined(OPENSSL_IS_AWSLC )
175
- static int s2n_evp_pkey_p_hash_alloc (struct s2n_prf_working_space * ws )
176
- {
177
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .evp_digest .ctx = S2N_EVP_MD_CTX_NEW ());
178
- return 0 ;
179
- }
180
-
181
- static int s2n_evp_pkey_p_hash_digest_init (struct s2n_prf_working_space * ws )
182
- {
183
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .evp_digest .md );
184
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .evp_digest .ctx );
185
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .ctx .evp_pkey );
186
-
187
- 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 ),
188
- S2N_ERR_P_HASH_INIT_FAILED );
189
-
190
- return 0 ;
191
- }
192
-
193
- static int s2n_evp_pkey_p_hash_init (struct s2n_prf_working_space * ws , s2n_hmac_algorithm alg , struct s2n_blob * secret )
194
- {
195
- /* Initialize the message digest */
196
- POSIX_GUARD_RESULT (s2n_hmac_md_from_alg (alg , & ws -> p_hash .evp_hmac .evp_digest .md ));
197
-
198
- /* Initialize the mac key using the provided secret */
199
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .ctx .evp_pkey = EVP_PKEY_new_mac_key (EVP_PKEY_HMAC , NULL , secret -> data , secret -> size ));
200
-
201
- /* Initialize the message digest context with the above message digest and mac key */
202
- return s2n_evp_pkey_p_hash_digest_init (ws );
203
- }
204
-
205
- static int s2n_evp_pkey_p_hash_update (struct s2n_prf_working_space * ws , const void * data , uint32_t size )
206
- {
207
- POSIX_GUARD_OSSL (EVP_DigestSignUpdate (ws -> p_hash .evp_hmac .evp_digest .ctx , data , (size_t ) size ), S2N_ERR_P_HASH_UPDATE_FAILED );
208
-
209
- return 0 ;
210
- }
211
-
212
- static int s2n_evp_pkey_p_hash_final (struct s2n_prf_working_space * ws , void * digest , uint32_t size )
213
- {
214
- /* EVP_DigestSign API's require size_t data structures */
215
- size_t digest_size = size ;
216
-
217
- POSIX_GUARD_OSSL (EVP_DigestSignFinal (ws -> p_hash .evp_hmac .evp_digest .ctx , (unsigned char * ) digest , & digest_size ), S2N_ERR_P_HASH_FINAL_FAILED );
218
-
219
- return 0 ;
220
- }
221
-
222
- static int s2n_evp_pkey_p_hash_wipe (struct s2n_prf_working_space * ws )
223
- {
224
- POSIX_GUARD_OSSL (S2N_EVP_MD_CTX_RESET (ws -> p_hash .evp_hmac .evp_digest .ctx ), S2N_ERR_P_HASH_WIPE_FAILED );
225
-
226
- return 0 ;
227
- }
228
-
229
- static int s2n_evp_pkey_p_hash_reset (struct s2n_prf_working_space * ws )
230
- {
231
- POSIX_GUARD (s2n_evp_pkey_p_hash_wipe (ws ));
232
-
233
- /*
234
- * On some cleanup paths s2n_evp_pkey_p_hash_reset can be called before s2n_evp_pkey_p_hash_init so there is nothing
235
- * to reset.
236
- */
237
- if (ws -> p_hash .evp_hmac .ctx .evp_pkey == NULL ) {
238
- return S2N_SUCCESS ;
239
- }
240
- return s2n_evp_pkey_p_hash_digest_init (ws );
241
- }
242
-
243
- static int s2n_evp_pkey_p_hash_cleanup (struct s2n_prf_working_space * ws )
244
- {
245
- /* Prepare the workspace md_ctx for the next p_hash */
246
- POSIX_GUARD (s2n_evp_pkey_p_hash_wipe (ws ));
247
-
248
- /* Free mac key - PKEYs cannot be reused */
249
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .ctx .evp_pkey );
250
- EVP_PKEY_free (ws -> p_hash .evp_hmac .ctx .evp_pkey );
251
- ws -> p_hash .evp_hmac .ctx .evp_pkey = NULL ;
252
-
253
- return 0 ;
254
- }
255
-
256
- static int s2n_evp_pkey_p_hash_free (struct s2n_prf_working_space * ws )
257
- {
258
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .evp_digest .ctx );
259
- S2N_EVP_MD_CTX_FREE (ws -> p_hash .evp_hmac .evp_digest .ctx );
260
- ws -> p_hash .evp_hmac .evp_digest .ctx = NULL ;
261
-
262
- return 0 ;
263
- }
264
-
265
- static const struct s2n_p_hash_hmac s2n_evp_pkey_p_hash_hmac = {
266
- .alloc = & s2n_evp_pkey_p_hash_alloc ,
267
- .init = & s2n_evp_pkey_p_hash_init ,
268
- .update = & s2n_evp_pkey_p_hash_update ,
269
- .final = & s2n_evp_pkey_p_hash_final ,
270
- .reset = & s2n_evp_pkey_p_hash_reset ,
271
- .cleanup = & s2n_evp_pkey_p_hash_cleanup ,
272
- .free = & s2n_evp_pkey_p_hash_free ,
273
- };
274
- #else
275
- static int s2n_evp_hmac_p_hash_alloc (struct s2n_prf_working_space * ws )
276
- {
277
- POSIX_ENSURE_REF (ws -> p_hash .evp_hmac .ctx .hmac_ctx = HMAC_CTX_new ());
278
- return S2N_SUCCESS ;
279
- }
280
-
281
- static int s2n_evp_hmac_p_hash_init (struct s2n_prf_working_space * ws , s2n_hmac_algorithm alg , struct s2n_blob * secret )
282
- {
283
- /* Figure out the correct EVP_MD from s2n_hmac_algorithm */
284
- POSIX_GUARD_RESULT (s2n_hmac_md_from_alg (alg , & ws -> p_hash .evp_hmac .evp_digest .md ));
285
-
286
- /* Initialize the mac and digest */
287
- 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 );
288
- return S2N_SUCCESS ;
289
- }
290
-
291
- static int s2n_evp_hmac_p_hash_update (struct s2n_prf_working_space * ws , const void * data , uint32_t size )
292
- {
293
- POSIX_GUARD_OSSL (HMAC_Update (ws -> p_hash .evp_hmac .ctx .hmac_ctx , data , (size_t ) size ), S2N_ERR_P_HASH_UPDATE_FAILED );
294
- return S2N_SUCCESS ;
295
- }
296
-
297
- static int s2n_evp_hmac_p_hash_final (struct s2n_prf_working_space * ws , void * digest , uint32_t size )
298
- {
299
- /* HMAC_Final API's require size_t data structures */
300
- unsigned int digest_size = size ;
301
- POSIX_GUARD_OSSL (HMAC_Final (ws -> p_hash .evp_hmac .ctx .hmac_ctx , (unsigned char * ) digest , & digest_size ), S2N_ERR_P_HASH_FINAL_FAILED );
302
- return S2N_SUCCESS ;
303
- }
304
-
305
- static int s2n_evp_hmac_p_hash_reset (struct s2n_prf_working_space * ws )
306
- {
307
- POSIX_ENSURE_REF (ws );
308
- if (ws -> p_hash .evp_hmac .evp_digest .md == NULL ) {
309
- return S2N_SUCCESS ;
310
- }
311
- 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 );
312
- return S2N_SUCCESS ;
313
- }
314
-
315
- static int s2n_evp_hmac_p_hash_cleanup (struct s2n_prf_working_space * ws )
316
- {
317
- /* Prepare the workspace md_ctx for the next p_hash */
318
- HMAC_CTX_reset (ws -> p_hash .evp_hmac .ctx .hmac_ctx );
319
- return S2N_SUCCESS ;
320
- }
321
-
322
- static int s2n_evp_hmac_p_hash_free (struct s2n_prf_working_space * ws )
323
- {
324
- HMAC_CTX_free (ws -> p_hash .evp_hmac .ctx .hmac_ctx );
325
- return S2N_SUCCESS ;
326
- }
327
-
328
- static const struct s2n_p_hash_hmac s2n_evp_hmac_p_hash_hmac = {
329
- .alloc = & s2n_evp_hmac_p_hash_alloc ,
330
- .init = & s2n_evp_hmac_p_hash_init ,
331
- .update = & s2n_evp_hmac_p_hash_update ,
332
- .final = & s2n_evp_hmac_p_hash_final ,
333
- .reset = & s2n_evp_hmac_p_hash_reset ,
334
- .cleanup = & s2n_evp_hmac_p_hash_cleanup ,
335
- .free = & s2n_evp_hmac_p_hash_free ,
336
- };
337
- #endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) */
338
-
339
174
static int s2n_hmac_p_hash_new (struct s2n_prf_working_space * ws )
340
175
{
341
176
POSIX_GUARD (s2n_hmac_new (& ws -> p_hash .s2n_hmac ));
342
-
343
177
return s2n_hmac_init (& ws -> p_hash .s2n_hmac , S2N_HMAC_NONE , NULL , 0 );
344
178
}
345
179
@@ -389,13 +223,24 @@ static const struct s2n_p_hash_hmac s2n_internal_p_hash_hmac = {
389
223
.free = & s2n_hmac_p_hash_free ,
390
224
};
391
225
226
+ /*
227
+ * For now, use the internal s2n-tls hmac abstraction.
228
+ * However, that is a custom implementation of hmac built on hashes.
229
+ * Ideally we should stop using our custom implementation here and switch
230
+ * to using a libcrypto implementation. Unfortunately, what each libcrypto
231
+ * can support varies a lot for HMACs.
232
+ *
233
+ * For historical reference, there used to be two other hmac implementations:
234
+ * https://github.com/aws/s2n-tls/blob/711ee0df658cd7c44088cf7a1b20a9f3cf5296d6/tls/s2n_prf.c#L174-L337
235
+ * - s2n_evp_hmac_p_hash_hmac required the HMAC_CTX_* methods, which are missing
236
+ * from openssl-1.0.2.
237
+ * - s2n_evp_pkey_p_hash_hmac required the EVP_PKEY_new_mac_key method, which is
238
+ * missing from some versions of awslc. EVP_PKEY_new_mac_key can be replaced
239
+ * by the EVP_PKEY_new_raw_private_key method, but that is missing from openssl-1.0.2.
240
+ */
392
241
const struct s2n_p_hash_hmac * s2n_get_hmac_implementation ()
393
242
{
394
- #if defined(OPENSSL_IS_BORINGSSL ) || defined(OPENSSL_IS_AWSLC )
395
- return s2n_is_in_fips_mode () ? & s2n_evp_hmac_p_hash_hmac : & s2n_internal_p_hash_hmac ;
396
- #else
397
- return s2n_is_in_fips_mode () ? & s2n_evp_pkey_p_hash_hmac : & s2n_internal_p_hash_hmac ;
398
- #endif
243
+ return & s2n_internal_p_hash_hmac ;
399
244
}
400
245
401
246
static int s2n_p_hash (struct s2n_prf_working_space * ws , s2n_hmac_algorithm alg , struct s2n_blob * secret , struct s2n_blob * label ,
@@ -405,6 +250,7 @@ static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg,
405
250
POSIX_GUARD (s2n_hmac_digest_size (alg , & digest_size ));
406
251
407
252
const struct s2n_p_hash_hmac * hmac = s2n_get_hmac_implementation ();
253
+ POSIX_ENSURE_REF (hmac );
408
254
409
255
/* First compute hmac(secret + A(0)) */
410
256
POSIX_GUARD (hmac -> init (ws , alg , secret ));
@@ -471,6 +317,7 @@ S2N_RESULT s2n_prf_new(struct s2n_connection *conn)
471
317
472
318
/* Allocate the hmac state */
473
319
const struct s2n_p_hash_hmac * hmac_impl = s2n_get_hmac_implementation ();
320
+ RESULT_ENSURE_REF (hmac_impl );
474
321
RESULT_GUARD_POSIX (hmac_impl -> alloc (conn -> prf_space ));
475
322
return S2N_RESULT_OK ;
476
323
}
@@ -481,6 +328,7 @@ S2N_RESULT s2n_prf_wipe(struct s2n_connection *conn)
481
328
RESULT_ENSURE_REF (conn -> prf_space );
482
329
483
330
const struct s2n_p_hash_hmac * hmac_impl = s2n_get_hmac_implementation ();
331
+ RESULT_ENSURE_REF (hmac_impl );
484
332
RESULT_GUARD_POSIX (hmac_impl -> reset (conn -> prf_space ));
485
333
486
334
return S2N_RESULT_OK ;
@@ -494,6 +342,7 @@ S2N_RESULT s2n_prf_free(struct s2n_connection *conn)
494
342
}
495
343
496
344
const struct s2n_p_hash_hmac * hmac_impl = s2n_get_hmac_implementation ();
345
+ RESULT_ENSURE_REF (hmac_impl );
497
346
RESULT_GUARD_POSIX (hmac_impl -> free (conn -> prf_space ));
498
347
499
348
RESULT_GUARD_POSIX (s2n_free_object ((uint8_t * * ) & conn -> prf_space , sizeof (struct s2n_prf_working_space )));
0 commit comments