11 #include "sw/device/lib/crypto/drivers/aes.h"
12 #include "sw/device/lib/crypto/drivers/keymgr.h"
13 #include "sw/device/lib/crypto/impl/aes_gcm/aes_gcm.h"
14 #include "sw/device/lib/crypto/impl/aes_gcm/ghash.h"
15 #include "sw/device/lib/crypto/impl/aes_kwp/aes_kwp.h"
16 #include "sw/device/lib/crypto/impl/integrity.h"
17 #include "sw/device/lib/crypto/impl/keyblob.h"
18 #include "sw/device/lib/crypto/impl/status.h"
22 #define MODULE_ID MAKE_MODULE_ID('a', 'e', 's')
34 "Size of AES-GCM context object for top-level API must be at "
35 "least as large as the context for the "
36 "underlying implementation.");
37 static_assert(
alignof(aes_gcm_context_t) >=
alignof(uint32_t),
38 "Internal AES-GCM context object must be word-aligned for use "
39 "with `hardened_memcpy`.");
41 "Key configuration size should be a multiple of 32 bits");
45 static_assert(
sizeof(aes_gcm_context_t) %
sizeof(uint32_t) == 0,
46 "Internal AES-GCM context object must be a multiple of the word "
47 "size for use with `hardened_memcpy`.");
49 kAesGcmContextNumWords =
sizeof(aes_gcm_context_t) /
sizeof(uint32_t),
58 static inline void gcm_context_save(aes_gcm_context_t *internal_ctx,
61 kAesGcmContextNumWords);
71 aes_gcm_context_t *internal_ctx) {
73 kAesGcmContextNumWords);
92 if (launder32(integrity_blinded_key_check(blinded_key)) !=
94 return OTCRYPTO_BAD_ARGS;
103 keyblob_to_keymgr_diversification(blinded_key, &diversification));
104 HARDENED_TRY(keymgr_generate_key_aes(diversification));
111 HARDENED_TRY(keyblob_to_shares(blinded_key, &share0, &share1));
115 return OTCRYPTO_BAD_ARGS;
120 if (blinded_key->keyblob == NULL) {
121 return OTCRYPTO_BAD_ARGS;
125 switch (blinded_key->config.key_mode) {
126 case kOtcryptoKeyModeAesEcb:
129 case kOtcryptoKeyModeAesCbc:
132 case kOtcryptoKeyModeAesCfb:
135 case kOtcryptoKeyModeAesOfb:
138 case kOtcryptoKeyModeAesCtr:
142 return OTCRYPTO_BAD_ARGS;
147 return OTCRYPTO_BAD_ARGS;
170 const size_t partial_data_len,
172 if (partial_data_len >= kAesBlockNumBytes) {
173 return OTCRYPTO_BAD_ARGS;
178 char *padding = ((
char *)block->data) + partial_data_len;
182 size_t padding_len = kAesBlockNumBytes - partial_data_len;
184 switch (launder32(padding_mode)) {
185 case kOtcryptoAesPaddingPkcs7:
187 memset(padding, (uint8_t)padding_len, padding_len);
190 case kOtcryptoAesPaddingIso9797M2:
192 memset(padding, 0x0, padding_len);
196 case kOtcryptoAesPaddingNull:
198 return OTCRYPTO_RECOV_ERR;
201 return OTCRYPTO_BAD_ARGS;
215 static status_t num_padded_blocks_get(
size_t plaintext_len,
217 size_t *num_blocks) {
218 size_t num_full_blocks = plaintext_len / kAesBlockNumBytes;
220 if (padding == kOtcryptoAesPaddingNull) {
222 if (num_full_blocks * kAesBlockNumBytes != plaintext_len) {
223 return OTCRYPTO_BAD_ARGS;
226 *num_blocks = num_full_blocks;
229 HARDENED_CHECK_NE(padding, kOtcryptoAesPaddingNull);
233 *num_blocks = num_full_blocks + 1;
251 size_t num_full_blocks = input.len / kAesBlockNumBytes;
255 HARDENED_CHECK_LE(index, num_full_blocks + 1);
257 if (launder32(index) < num_full_blocks) {
258 HARDENED_CHECK_LT(index, num_full_blocks);
262 memcpy(block->data, &input.data[index * kAesBlockNumBytes],
266 HARDENED_CHECK_GE(index, num_full_blocks);
270 size_t partial_data_len = input.len % kAesBlockNumBytes;
271 memcpy(block->data, &input.data[index * kAesBlockNumBytes], partial_data_len);
274 HARDENED_TRY(aes_padding_apply(padding, partial_data_len, block));
280 size_t *padded_len) {
281 size_t padded_nblocks;
283 num_padded_blocks_get(plaintext_len, aes_padding, &padded_nblocks));
284 *padded_len = padded_nblocks * kAesBlockNumBytes;
296 if (key == NULL || (aes_mode != kOtcryptoAesModeEcb && iv.data == NULL) ||
297 cipher_input.data == NULL || cipher_output.data == NULL) {
298 return OTCRYPTO_BAD_ARGS;
303 size_t input_nblocks;
304 if (aes_operation == kOtcryptoAesOperationEncrypt) {
306 num_padded_blocks_get(cipher_input.len, aes_padding, &input_nblocks));
307 }
else if (aes_operation == kOtcryptoAesOperationDecrypt) {
310 if (launder32(cipher_input.len) % kAesBlockNumBytes != 0) {
311 return OTCRYPTO_BAD_ARGS;
314 input_nblocks = cipher_input.len / kAesBlockNumBytes;
320 if (cipher_input.len == 0 ||
321 launder32(cipher_output.len) != input_nblocks * kAesBlockNumBytes) {
322 return OTCRYPTO_BAD_ARGS;
329 if (aes_mode == launder32(kAesCipherModeEcb)) {
332 HARDENED_CHECK_NE(aes_mode, kAesCipherModeEcb);
335 if (launder32(iv.len) != kAesBlockNumWords) {
336 return OTCRYPTO_BAD_ARGS;
344 HARDENED_TRY(aes_key_construct(key, aes_mode, &
aes_key));
347 switch (aes_operation) {
348 case kOtcryptoAesOperationEncrypt:
349 HARDENED_TRY(aes_encrypt_begin(
aes_key, &aes_iv));
351 case kOtcryptoAesOperationDecrypt:
352 HARDENED_TRY(aes_decrypt_begin(
aes_key, &aes_iv));
355 return OTCRYPTO_BAD_ARGS;
383 const size_t block_offset = input_nblocks >= 3 ? 2 : 1;
390 for (i = 0; launder32(i) < block_offset; ++i) {
391 HARDENED_TRY(get_block(cipher_input, aes_padding, i, &block_in));
392 TRY(aes_update(NULL, &block_in));
399 for (i = block_offset; launder32(i) < input_nblocks; ++i) {
400 HARDENED_TRY(get_block(cipher_input, aes_padding, i, &block_in));
401 TRY(aes_update(&block_out, &block_in));
403 memcpy(&cipher_output.data[(i - block_offset) * kAesBlockNumBytes],
404 block_out.data, kAesBlockNumBytes);
411 for (i = block_offset; launder32(i) > 0; --i) {
412 HARDENED_TRY(aes_update(&block_out, NULL));
414 memcpy(&cipher_output.data[(input_nblocks - i) * kAesBlockNumBytes],
415 block_out.data, kAesBlockNumBytes);
421 if (aes_mode == launder32(kAesCipherModeEcb)) {
422 HARDENED_TRY(aes_end(NULL));
424 HARDENED_TRY(aes_end(&aes_iv));
430 HARDENED_TRY(keymgr_sideload_clear_aes());
448 if (launder32(integrity_blinded_key_check(blinded_key)) !=
450 return OTCRYPTO_BAD_ARGS;
456 if (launder32((uint32_t)blinded_key->config.key_mode) !=
457 kOtcryptoKeyModeAesGcm) {
458 return OTCRYPTO_BAD_ARGS;
470 if (blinded_key->keyblob == NULL) {
471 return OTCRYPTO_BAD_ARGS;
477 if (launder32(blinded_key->keyblob_length) != kKeyblobHwBackedBytes) {
478 return OTCRYPTO_BAD_ARGS;
489 HARDENED_TRY(keyblob_to_shares(blinded_key, &share0, &share1));
494 return OTCRYPTO_BAD_ARGS;
508 status_t aes_gcm_check_tag_length(
size_t word_len,
511 switch (launder32(tag_len)) {
512 case kOtcryptoAesGcmTagLen128:
516 case kOtcryptoAesGcmTagLen96:
520 case kOtcryptoAesGcmTagLen64:
524 case kOtcryptoAesGcmTagLen32:
530 return OTCRYPTO_BAD_ARGS;
532 HARDENED_CHECK_GT(bit_len, 0);
535 if (launder32(word_len) != bit_len / 32) {
536 return OTCRYPTO_BAD_ARGS;
542 HARDENED_CHECK_LT(0, word_len);
543 HARDENED_CHECK_LE(word_len, kAesBlockNumWords);
568 return OTCRYPTO_BAD_ARGS;
572 HARDENED_TRY(keyblob_buffer_to_keymgr_diversification(
573 key.
key_shares[0], kOtcryptoKeyModeAesGcm, &diversification));
574 return keymgr_generate_key_aes(diversification);
593 return OTCRYPTO_BAD_ARGS;
596 return keymgr_sideload_clear_aes();
608 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
609 return OTCRYPTO_BAD_ARGS;
614 if ((aad.len != 0 && aad.data == NULL) ||
615 (ciphertext.len != 0 && ciphertext.data == NULL) ||
616 (plaintext.len != 0 && plaintext.data == NULL)) {
617 return OTCRYPTO_BAD_ARGS;
621 if (launder32(ciphertext.len) != plaintext.len) {
622 return OTCRYPTO_BAD_ARGS;
627 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
631 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
632 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
635 HARDENED_TRY(aes_gcm_encrypt(
aes_key, iv.len, iv.data, plaintext.len,
636 plaintext.data, aad.len, aad.data, auth_tag.len,
637 auth_tag.data, ciphertext.data));
639 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
650 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
651 return OTCRYPTO_BAD_ARGS;
656 if ((aad.len != 0 && aad.data == NULL) ||
657 (ciphertext.len != 0 && ciphertext.data == NULL) ||
658 (plaintext.len != 0 && plaintext.data == NULL)) {
659 return OTCRYPTO_BAD_ARGS;
664 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
665 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
668 if (launder32(ciphertext.len) != plaintext.len) {
669 return OTCRYPTO_BAD_ARGS;
674 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
677 HARDENED_TRY(aes_gcm_decrypt(
aes_key, iv.len, iv.data, ciphertext.len,
678 ciphertext.data, aad.len, aad.data, auth_tag.len,
679 auth_tag.data, plaintext.data, success));
681 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
688 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
689 return OTCRYPTO_BAD_ARGS;
694 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
695 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
698 aes_gcm_context_t internal_ctx;
699 HARDENED_TRY(aes_gcm_encrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
702 gcm_context_save(&internal_ctx, ctx);
703 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
710 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
711 return OTCRYPTO_BAD_ARGS;
716 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
717 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
720 aes_gcm_context_t internal_ctx;
721 HARDENED_TRY(aes_gcm_decrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
724 gcm_context_save(&internal_ctx, ctx);
725 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
731 if (ctx == NULL || aad.data == NULL) {
732 return OTCRYPTO_BAD_ARGS;
741 aes_gcm_context_t internal_ctx;
742 gcm_context_restore(ctx, &internal_ctx);
743 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
746 HARDENED_TRY(aes_gcm_update_aad(&internal_ctx, aad.len, aad.data));
749 gcm_context_save(&internal_ctx, ctx);
750 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
757 if (ctx == NULL || input.data == NULL || output.data == NULL ||
758 output_bytes_written == NULL) {
759 return OTCRYPTO_BAD_ARGS;
761 *output_bytes_written = 0;
763 if (input.len == 0) {
769 aes_gcm_context_t internal_ctx;
770 gcm_context_restore(ctx, &internal_ctx);
771 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
775 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
776 if (input.len > UINT32_MAX - partial_block_len) {
777 return OTCRYPTO_BAD_ARGS;
779 size_t min_output_blocks =
780 (partial_block_len + input.len) / kAesBlockNumBytes;
781 size_t min_output_len = min_output_blocks * kAesBlockNumBytes;
782 if (output.len < min_output_len) {
783 return OTCRYPTO_BAD_ARGS;
787 HARDENED_TRY(aes_gcm_update_encrypted_data(
788 &internal_ctx, input.len, input.data, output_bytes_written, output.data));
791 gcm_context_save(&internal_ctx, ctx);
792 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
800 if (ctx == NULL || ciphertext_bytes_written == NULL ||
801 auth_tag.data == NULL) {
802 return OTCRYPTO_BAD_ARGS;
804 if (ciphertext.len != 0 && ciphertext.data == NULL) {
805 return OTCRYPTO_BAD_ARGS;
807 *ciphertext_bytes_written = 0;
810 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
813 aes_gcm_context_t internal_ctx;
814 gcm_context_restore(ctx, &internal_ctx);
815 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
819 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
820 if (ciphertext.len < partial_block_len) {
821 return OTCRYPTO_BAD_ARGS;
825 HARDENED_TRY(aes_gcm_encrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
826 ciphertext_bytes_written,
831 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
839 if (ctx == NULL || plaintext_bytes_written == NULL || auth_tag.data == NULL ||
841 return OTCRYPTO_BAD_ARGS;
843 if (plaintext.len != 0 && plaintext.data == NULL) {
844 return OTCRYPTO_BAD_ARGS;
846 *plaintext_bytes_written = 0;
850 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
853 aes_gcm_context_t internal_ctx;
854 gcm_context_restore(ctx, &internal_ctx);
855 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
859 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
860 if (plaintext.len < partial_block_len) {
861 return OTCRYPTO_BAD_ARGS;
865 HARDENED_TRY(aes_gcm_decrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
866 plaintext_bytes_written, plaintext.data,
871 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
879 if (keyblob_num_words(config) > UINT32_MAX - config_num_words - 2) {
880 return OTCRYPTO_BAD_ARGS;
888 *wrapped_num_words = config_num_words + 2 + keyblob_num_words(config);
891 *wrapped_num_words += 2;
894 if (*wrapped_num_words % 2 == 1) {
895 *wrapped_num_words += 1;
914 return OTCRYPTO_BAD_ARGS;
919 if (launder32((uint32_t)key_kek->config.key_mode) != kOtcryptoKeyModeAesKwp) {
920 return OTCRYPTO_BAD_ARGS;
931 HARDENED_TRY(keyblob_to_keymgr_diversification(key_kek, &diversification));
932 HARDENED_TRY(keymgr_generate_key_aes(diversification));
934 return OTCRYPTO_BAD_ARGS;
944 HARDENED_TRY(keyblob_to_shares(key_kek, &share0, &share1));
954 if (key_to_wrap == NULL || key_to_wrap->keyblob == NULL || key_kek == NULL ||
955 key_kek->keyblob == NULL || wrapped_key.data == NULL) {
956 return OTCRYPTO_BAD_ARGS;
960 if (launder32(integrity_blinded_key_check(key_to_wrap)) !=
962 return OTCRYPTO_BAD_ARGS;
970 if (wrapped_key.len != exp_len) {
971 return OTCRYPTO_BAD_ARGS;
977 HARDENED_TRY(aes_kwp_key_construct(key_kek, &kek));
980 uint32_t keyblob_words = keyblob_num_words(key_to_wrap->config);
981 if (key_to_wrap->keyblob_length != keyblob_words *
sizeof(uint32_t)) {
982 return OTCRYPTO_BAD_ARGS;
987 return OTCRYPTO_BAD_ARGS;
993 size_t plaintext_num_words = config_words + 2 + keyblob_words;
994 uint32_t plaintext[plaintext_num_words];
995 hardened_memcpy(plaintext, (uint32_t *)&key_to_wrap->config, config_words);
996 plaintext[config_words] = key_to_wrap->checksum;
997 plaintext[config_words + 1] = keyblob_words;
1002 return aes_kwp_wrap(kek, plaintext,
sizeof(plaintext), wrapped_key.data);
1011 if (wrapped_key.data == NULL || key_kek == NULL || key_kek->keyblob == NULL ||
1012 success == NULL || unwrapped_key == NULL ||
1013 unwrapped_key->keyblob == NULL) {
1014 return OTCRYPTO_BAD_ARGS;
1020 HARDENED_TRY(aes_kwp_key_construct(key_kek, &kek));
1024 return OTCRYPTO_BAD_ARGS;
1028 uint32_t plaintext[wrapped_key.len];
1029 HARDENED_TRY(aes_kwp_unwrap(kek, wrapped_key.data,
1030 wrapped_key.len *
sizeof(uint32_t), success,
1044 hardened_memcpy((uint32_t *)&unwrapped_key->config, plaintext, config_words);
1047 unwrapped_key->checksum = plaintext[config_words];
1048 uint32_t keyblob_words = plaintext[config_words + 1];
1049 if (keyblob_words != keyblob_num_words(unwrapped_key->config)) {
1055 if (unwrapped_key->keyblob_length != keyblob_words *
sizeof(uint32_t)) {
1056 return OTCRYPTO_BAD_ARGS;
1062 *success = integrity_blinded_key_check(unwrapped_key);