11 #include "sw/device/lib/crypto/drivers/aes.h"
12 #include "sw/device/lib/crypto/drivers/entropy.h"
13 #include "sw/device/lib/crypto/drivers/keymgr.h"
14 #include "sw/device/lib/crypto/drivers/rv_core_ibex.h"
15 #include "sw/device/lib/crypto/impl/aes_gcm/aes_gcm.h"
16 #include "sw/device/lib/crypto/impl/aes_gcm/ghash.h"
17 #include "sw/device/lib/crypto/impl/integrity.h"
18 #include "sw/device/lib/crypto/impl/keyblob.h"
19 #include "sw/device/lib/crypto/impl/status.h"
23 #define MODULE_ID MAKE_MODULE_ID('a', 'g', 'c')
27 "Size of AES-GCM context object for top-level API must be at "
28 "least as large as the context for the "
29 "underlying implementation.");
30 static_assert(
alignof(aes_gcm_context_t) >=
alignof(uint32_t),
31 "Internal AES-GCM context object must be word-aligned for use "
32 "with `hardened_memcpy`.");
34 "Key configuration size should be a multiple of 32 bits");
38 static_assert(
sizeof(aes_gcm_context_t) %
sizeof(uint32_t) == 0,
39 "Internal AES-GCM context object must be a multiple of the word "
40 "size for use with `hardened_memcpy`.");
42 kAesGcmContextNumWords =
sizeof(aes_gcm_context_t) /
sizeof(uint32_t),
51 static inline void gcm_context_save(aes_gcm_context_t *internal_ctx,
54 kAesGcmContextNumWords);
64 aes_gcm_context_t *internal_ctx) {
66 kAesGcmContextNumWords);
81 if (launder32(integrity_blinded_key_check(blinded_key)) !=
83 return OTCRYPTO_BAD_ARGS;
89 if (launder32((uint32_t)blinded_key->config.key_mode) !=
90 kOtcryptoKeyModeAesGcm) {
91 return OTCRYPTO_BAD_ARGS;
103 if (blinded_key->keyblob == NULL) {
104 return OTCRYPTO_BAD_ARGS;
110 if (launder32(blinded_key->keyblob_length) != kKeyblobHwBackedBytes) {
111 return OTCRYPTO_BAD_ARGS;
122 HARDENED_TRY(keyblob_to_shares(blinded_key, &share0, &share1));
127 return OTCRYPTO_BAD_ARGS;
141 status_t aes_gcm_check_tag_length(
size_t word_len,
144 switch (launder32(tag_len)) {
145 case kOtcryptoAesGcmTagLen128:
149 case kOtcryptoAesGcmTagLen96:
153 case kOtcryptoAesGcmTagLen64:
157 case kOtcryptoAesGcmTagLen32:
163 return OTCRYPTO_BAD_ARGS;
165 HARDENED_CHECK_GT(bit_len, 0);
168 if (launder32(word_len) != bit_len / 32) {
169 return OTCRYPTO_BAD_ARGS;
175 HARDENED_CHECK_LT(0, word_len);
176 HARDENED_CHECK_LE(word_len, kAesBlockNumWords);
201 return OTCRYPTO_BAD_ARGS;
205 HARDENED_TRY(keyblob_buffer_to_keymgr_diversification(
206 key.
key_shares[0], kOtcryptoKeyModeAesGcm, &diversification));
207 return keymgr_generate_key_aes(diversification);
226 return OTCRYPTO_BAD_ARGS;
229 return keymgr_sideload_clear_aes();
241 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
242 return OTCRYPTO_BAD_ARGS;
247 if ((aad.len != 0 && aad.data == NULL) ||
248 (ciphertext.len != 0 && ciphertext.data == NULL) ||
249 (plaintext.len != 0 && plaintext.data == NULL)) {
250 return OTCRYPTO_BAD_ARGS;
254 if (launder32(ciphertext.len) != plaintext.len) {
255 return OTCRYPTO_BAD_ARGS;
260 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
264 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
265 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
268 HARDENED_TRY(aes_gcm_encrypt(
aes_key, iv.len, iv.data, plaintext.len,
269 plaintext.data, aad.len, aad.data, auth_tag.len,
270 auth_tag.data, ciphertext.data));
272 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
283 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
284 return OTCRYPTO_BAD_ARGS;
289 if ((aad.len != 0 && aad.data == NULL) ||
290 (ciphertext.len != 0 && ciphertext.data == NULL) ||
291 (plaintext.len != 0 && plaintext.data == NULL)) {
292 return OTCRYPTO_BAD_ARGS;
297 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
298 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
301 if (launder32(ciphertext.len) != plaintext.len) {
302 return OTCRYPTO_BAD_ARGS;
307 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
310 HARDENED_TRY(aes_gcm_decrypt(
aes_key, iv.len, iv.data, ciphertext.len,
311 ciphertext.data, aad.len, aad.data, auth_tag.len,
312 auth_tag.data, plaintext.data, success));
314 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
321 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
322 return OTCRYPTO_BAD_ARGS;
327 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
328 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
331 aes_gcm_context_t internal_ctx;
332 HARDENED_TRY(aes_gcm_encrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
335 gcm_context_save(&internal_ctx, ctx);
336 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
343 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
344 return OTCRYPTO_BAD_ARGS;
349 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
350 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
353 aes_gcm_context_t internal_ctx;
354 HARDENED_TRY(aes_gcm_decrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
357 gcm_context_save(&internal_ctx, ctx);
358 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
364 if (ctx == NULL || aad.data == NULL) {
365 return OTCRYPTO_BAD_ARGS;
374 aes_gcm_context_t internal_ctx;
375 gcm_context_restore(ctx, &internal_ctx);
376 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
379 HARDENED_TRY(aes_gcm_update_aad(&internal_ctx, aad.len, aad.data));
382 gcm_context_save(&internal_ctx, ctx);
383 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
390 if (ctx == NULL || input.data == NULL || output.data == NULL ||
391 output_bytes_written == NULL) {
392 return OTCRYPTO_BAD_ARGS;
394 *output_bytes_written = 0;
396 if (input.len == 0) {
402 aes_gcm_context_t internal_ctx;
403 gcm_context_restore(ctx, &internal_ctx);
404 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
408 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
409 if (input.len > UINT32_MAX - partial_block_len) {
410 return OTCRYPTO_BAD_ARGS;
412 size_t min_output_blocks =
413 (partial_block_len + input.len) / kAesBlockNumBytes;
414 size_t min_output_len = min_output_blocks * kAesBlockNumBytes;
415 if (output.len < min_output_len) {
416 return OTCRYPTO_BAD_ARGS;
420 HARDENED_TRY(aes_gcm_update_encrypted_data(
421 &internal_ctx, input.len, input.data, output_bytes_written, output.data));
424 gcm_context_save(&internal_ctx, ctx);
425 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
433 if (ctx == NULL || ciphertext_bytes_written == NULL ||
434 auth_tag.data == NULL) {
435 return OTCRYPTO_BAD_ARGS;
437 if (ciphertext.len != 0 && ciphertext.data == NULL) {
438 return OTCRYPTO_BAD_ARGS;
440 *ciphertext_bytes_written = 0;
443 HARDENED_TRY(entropy_complex_check());
446 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
449 aes_gcm_context_t internal_ctx;
450 gcm_context_restore(ctx, &internal_ctx);
451 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
455 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
456 if (ciphertext.len < partial_block_len) {
457 return OTCRYPTO_BAD_ARGS;
461 HARDENED_TRY(aes_gcm_encrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
462 ciphertext_bytes_written,
467 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
475 if (ctx == NULL || plaintext_bytes_written == NULL || auth_tag.data == NULL ||
477 return OTCRYPTO_BAD_ARGS;
479 if (plaintext.len != 0 && plaintext.data == NULL) {
480 return OTCRYPTO_BAD_ARGS;
482 *plaintext_bytes_written = 0;
486 HARDENED_TRY(entropy_complex_check());
489 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
492 aes_gcm_context_t internal_ctx;
493 gcm_context_restore(ctx, &internal_ctx);
494 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
498 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
499 if (plaintext.len < partial_block_len) {
500 return OTCRYPTO_BAD_ARGS;
504 HARDENED_TRY(aes_gcm_decrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
505 plaintext_bytes_written, plaintext.data,
510 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));