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/integrity.h"
14 #include "sw/device/lib/crypto/impl/keyblob.h"
15 #include "sw/device/lib/crypto/impl/status.h"
19 #define MODULE_ID MAKE_MODULE_ID('a', 'e', 's')
45 if (launder32(integrity_blinded_key_check(blinded_key)) !=
47 return OTCRYPTO_BAD_ARGS;
56 keyblob_to_keymgr_diversification(blinded_key, &diversification));
57 HARDENED_TRY(keymgr_generate_key_aes(diversification));
64 HARDENED_TRY(keyblob_to_shares(blinded_key, &share0, &share1));
68 return OTCRYPTO_BAD_ARGS;
73 if (blinded_key->keyblob == NULL) {
74 return OTCRYPTO_BAD_ARGS;
78 switch (blinded_key->config.key_mode) {
79 case kOtcryptoKeyModeAesEcb:
82 case kOtcryptoKeyModeAesCbc:
85 case kOtcryptoKeyModeAesCfb:
88 case kOtcryptoKeyModeAesOfb:
91 case kOtcryptoKeyModeAesCtr:
95 return OTCRYPTO_BAD_ARGS;
100 return OTCRYPTO_BAD_ARGS;
123 const size_t partial_data_len,
125 if (partial_data_len >= kAesBlockNumBytes) {
126 return OTCRYPTO_BAD_ARGS;
131 char *padding = ((
char *)block->data) + partial_data_len;
135 size_t padding_len = kAesBlockNumBytes - partial_data_len;
137 switch (launder32(padding_mode)) {
138 case kOtcryptoAesPaddingPkcs7:
140 memset(padding, (uint8_t)padding_len, padding_len);
143 case kOtcryptoAesPaddingIso9797M2:
145 memset(padding, 0x0, padding_len);
149 case kOtcryptoAesPaddingNull:
151 return OTCRYPTO_RECOV_ERR;
154 return OTCRYPTO_BAD_ARGS;
168 static status_t num_padded_blocks_get(
size_t plaintext_len,
170 size_t *num_blocks) {
171 size_t num_full_blocks = plaintext_len / kAesBlockNumBytes;
173 if (padding == kOtcryptoAesPaddingNull) {
175 if (num_full_blocks * kAesBlockNumBytes != plaintext_len) {
176 return OTCRYPTO_BAD_ARGS;
179 *num_blocks = num_full_blocks;
182 HARDENED_CHECK_NE(padding, kOtcryptoAesPaddingNull);
186 *num_blocks = num_full_blocks + 1;
204 size_t num_full_blocks = input.len / kAesBlockNumBytes;
208 HARDENED_CHECK_LE(index, num_full_blocks + 1);
210 if (launder32(index) < num_full_blocks) {
211 HARDENED_CHECK_LT(index, num_full_blocks);
215 memcpy(block->data, &input.data[index * kAesBlockNumBytes],
219 HARDENED_CHECK_GE(index, num_full_blocks);
223 size_t partial_data_len = input.len % kAesBlockNumBytes;
224 memcpy(block->data, &input.data[index * kAesBlockNumBytes], partial_data_len);
227 HARDENED_TRY(aes_padding_apply(padding, partial_data_len, block));
233 size_t *padded_len) {
234 size_t padded_nblocks;
236 num_padded_blocks_get(plaintext_len, aes_padding, &padded_nblocks));
237 *padded_len = padded_nblocks * kAesBlockNumBytes;
249 if (key == NULL || (aes_mode != kOtcryptoAesModeEcb && iv.data == NULL) ||
250 cipher_input.data == NULL || cipher_output.data == NULL) {
251 return OTCRYPTO_BAD_ARGS;
256 size_t input_nblocks;
257 if (aes_operation == kOtcryptoAesOperationEncrypt) {
259 num_padded_blocks_get(cipher_input.len, aes_padding, &input_nblocks));
260 }
else if (aes_operation == kOtcryptoAesOperationDecrypt) {
263 if (launder32(cipher_input.len) % kAesBlockNumBytes != 0) {
264 return OTCRYPTO_BAD_ARGS;
267 input_nblocks = cipher_input.len / kAesBlockNumBytes;
273 if (cipher_input.len == 0 ||
274 launder32(cipher_output.len) != input_nblocks * kAesBlockNumBytes) {
275 return OTCRYPTO_BAD_ARGS;
282 if (aes_mode == launder32(kAesCipherModeEcb)) {
285 HARDENED_CHECK_NE(aes_mode, kAesCipherModeEcb);
288 if (launder32(iv.len) != kAesBlockNumWords) {
289 return OTCRYPTO_BAD_ARGS;
297 HARDENED_TRY(aes_key_construct(key, aes_mode, &
aes_key));
300 switch (aes_operation) {
301 case kOtcryptoAesOperationEncrypt:
302 HARDENED_TRY(aes_encrypt_begin(
aes_key, &aes_iv));
304 case kOtcryptoAesOperationDecrypt:
305 HARDENED_TRY(aes_decrypt_begin(
aes_key, &aes_iv));
308 return OTCRYPTO_BAD_ARGS;
336 const size_t block_offset = input_nblocks >= 3 ? 2 : 1;
343 for (i = 0; launder32(i) < block_offset; ++i) {
344 HARDENED_TRY(get_block(cipher_input, aes_padding, i, &block_in));
345 TRY(aes_update(NULL, &block_in));
352 for (i = block_offset; launder32(i) < input_nblocks; ++i) {
353 HARDENED_TRY(get_block(cipher_input, aes_padding, i, &block_in));
354 TRY(aes_update(&block_out, &block_in));
356 memcpy(&cipher_output.data[(i - block_offset) * kAesBlockNumBytes],
357 block_out.data, kAesBlockNumBytes);
364 for (i = block_offset; launder32(i) > 0; --i) {
365 HARDENED_TRY(aes_update(&block_out, NULL));
367 memcpy(&cipher_output.data[(input_nblocks - i) * kAesBlockNumBytes],
368 block_out.data, kAesBlockNumBytes);
374 if (aes_mode == launder32(kAesCipherModeEcb)) {
375 HARDENED_TRY(aes_end(NULL));
377 HARDENED_TRY(aes_end(&aes_iv));
383 HARDENED_TRY(keymgr_sideload_clear_aes());