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/integrity.h"
16 #include "sw/device/lib/crypto/impl/keyblob.h"
17 #include "sw/device/lib/crypto/impl/status.h"
21 #define MODULE_ID MAKE_MODULE_ID('a', 'g', 'c')
25 "Size of AES-GCM context object for top-level API must be at "
26 "least as large as the context for the "
27 "underlying implementation.");
28 static_assert(
alignof(aes_gcm_context_t) >=
alignof(uint32_t),
29 "Internal AES-GCM context object must be word-aligned for use "
30 "with `hardened_memcpy`.");
32 "Key configuration size should be a multiple of 32 bits");
36 static_assert(
sizeof(aes_gcm_context_t) %
sizeof(uint32_t) == 0,
37 "Internal AES-GCM context object must be a multiple of the word "
38 "size for use with `hardened_memcpy`.");
40 kAesGcmContextNumWords =
sizeof(aes_gcm_context_t) /
sizeof(uint32_t),
49 static inline void gcm_context_save(aes_gcm_context_t *internal_ctx,
52 kAesGcmContextNumWords);
62 aes_gcm_context_t *internal_ctx) {
64 kAesGcmContextNumWords);
79 if (launder32(integrity_blinded_key_check(blinded_key)) !=
81 return OTCRYPTO_BAD_ARGS;
87 if (launder32((uint32_t)blinded_key->config.key_mode) !=
88 kOtcryptoKeyModeAesGcm) {
89 return OTCRYPTO_BAD_ARGS;
101 if (blinded_key->keyblob == NULL) {
102 return OTCRYPTO_BAD_ARGS;
108 if (launder32(blinded_key->keyblob_length) != kKeyblobHwBackedBytes) {
109 return OTCRYPTO_BAD_ARGS;
120 HARDENED_TRY(keyblob_to_shares(blinded_key, &share0, &share1));
125 return OTCRYPTO_BAD_ARGS;
139 status_t aes_gcm_check_tag_length(
size_t word_len,
142 switch (launder32(tag_len)) {
143 case kOtcryptoAesGcmTagLen128:
147 case kOtcryptoAesGcmTagLen96:
151 case kOtcryptoAesGcmTagLen64:
155 case kOtcryptoAesGcmTagLen32:
161 return OTCRYPTO_BAD_ARGS;
163 HARDENED_CHECK_GT(bit_len, 0);
166 if (launder32(word_len) != bit_len / 32) {
167 return OTCRYPTO_BAD_ARGS;
173 HARDENED_CHECK_LT(0, word_len);
174 HARDENED_CHECK_LE(word_len, kAesBlockNumWords);
199 return OTCRYPTO_BAD_ARGS;
203 HARDENED_TRY(keyblob_buffer_to_keymgr_diversification(
204 key.
key_shares[0], kOtcryptoKeyModeAesGcm, &diversification));
205 return keymgr_generate_key_aes(diversification);
224 return OTCRYPTO_BAD_ARGS;
227 return keymgr_sideload_clear_aes();
239 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
240 return OTCRYPTO_BAD_ARGS;
245 if ((aad.len != 0 && aad.data == NULL) ||
246 (ciphertext.len != 0 && ciphertext.data == NULL) ||
247 (plaintext.len != 0 && plaintext.data == NULL)) {
248 return OTCRYPTO_BAD_ARGS;
252 if (launder32(ciphertext.len) != plaintext.len) {
253 return OTCRYPTO_BAD_ARGS;
258 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
262 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
263 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
266 HARDENED_TRY(aes_gcm_encrypt(
aes_key, iv.len, iv.data, plaintext.len,
267 plaintext.data, aad.len, aad.data, auth_tag.len,
268 auth_tag.data, ciphertext.data));
270 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
281 if (key == NULL || iv.data == NULL || auth_tag.data == NULL) {
282 return OTCRYPTO_BAD_ARGS;
287 if ((aad.len != 0 && aad.data == NULL) ||
288 (ciphertext.len != 0 && ciphertext.data == NULL) ||
289 (plaintext.len != 0 && plaintext.data == NULL)) {
290 return OTCRYPTO_BAD_ARGS;
295 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
296 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
299 if (launder32(ciphertext.len) != plaintext.len) {
300 return OTCRYPTO_BAD_ARGS;
305 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
308 HARDENED_TRY(aes_gcm_decrypt(
aes_key, iv.len, iv.data, ciphertext.len,
309 ciphertext.data, aad.len, aad.data, auth_tag.len,
310 auth_tag.data, plaintext.data, success));
312 HARDENED_TRY(clear_key_if_sideloaded(
aes_key));
319 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
320 return OTCRYPTO_BAD_ARGS;
325 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
326 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
329 aes_gcm_context_t internal_ctx;
330 HARDENED_TRY(aes_gcm_encrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
333 gcm_context_save(&internal_ctx, ctx);
334 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
341 if (key == NULL || key->keyblob == NULL || iv.data == NULL || ctx == NULL) {
342 return OTCRYPTO_BAD_ARGS;
347 HARDENED_TRY(aes_gcm_key_construct(key, &
aes_key));
348 HARDENED_TRY(load_key_if_sideloaded(
aes_key));
351 aes_gcm_context_t internal_ctx;
352 HARDENED_TRY(aes_gcm_decrypt_init(
aes_key, iv.len, iv.data, &internal_ctx));
355 gcm_context_save(&internal_ctx, ctx);
356 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
362 if (ctx == NULL || aad.data == NULL) {
363 return OTCRYPTO_BAD_ARGS;
372 aes_gcm_context_t internal_ctx;
373 gcm_context_restore(ctx, &internal_ctx);
374 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
377 HARDENED_TRY(aes_gcm_update_aad(&internal_ctx, aad.len, aad.data));
380 gcm_context_save(&internal_ctx, ctx);
381 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
388 if (ctx == NULL || input.data == NULL || output.data == NULL ||
389 output_bytes_written == NULL) {
390 return OTCRYPTO_BAD_ARGS;
392 *output_bytes_written = 0;
394 if (input.len == 0) {
400 aes_gcm_context_t internal_ctx;
401 gcm_context_restore(ctx, &internal_ctx);
402 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
406 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
407 if (input.len > UINT32_MAX - partial_block_len) {
408 return OTCRYPTO_BAD_ARGS;
410 size_t min_output_blocks =
411 (partial_block_len + input.len) / kAesBlockNumBytes;
412 size_t min_output_len = min_output_blocks * kAesBlockNumBytes;
413 if (output.len < min_output_len) {
414 return OTCRYPTO_BAD_ARGS;
418 HARDENED_TRY(aes_gcm_update_encrypted_data(
419 &internal_ctx, input.len, input.data, output_bytes_written, output.data));
422 gcm_context_save(&internal_ctx, ctx);
423 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
431 if (ctx == NULL || ciphertext_bytes_written == NULL ||
432 auth_tag.data == NULL) {
433 return OTCRYPTO_BAD_ARGS;
435 if (ciphertext.len != 0 && ciphertext.data == NULL) {
436 return OTCRYPTO_BAD_ARGS;
438 *ciphertext_bytes_written = 0;
441 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
444 aes_gcm_context_t internal_ctx;
445 gcm_context_restore(ctx, &internal_ctx);
446 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
450 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
451 if (ciphertext.len < partial_block_len) {
452 return OTCRYPTO_BAD_ARGS;
456 HARDENED_TRY(aes_gcm_encrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
457 ciphertext_bytes_written,
462 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));
470 if (ctx == NULL || plaintext_bytes_written == NULL || auth_tag.data == NULL ||
472 return OTCRYPTO_BAD_ARGS;
474 if (plaintext.len != 0 && plaintext.data == NULL) {
475 return OTCRYPTO_BAD_ARGS;
477 *plaintext_bytes_written = 0;
481 HARDENED_TRY(aes_gcm_check_tag_length(auth_tag.len, tag_len));
484 aes_gcm_context_t internal_ctx;
485 gcm_context_restore(ctx, &internal_ctx);
486 HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
490 size_t partial_block_len = internal_ctx.input_len % kAesBlockNumBytes;
491 if (plaintext.len < partial_block_len) {
492 return OTCRYPTO_BAD_ARGS;
496 HARDENED_TRY(aes_gcm_decrypt_final(&internal_ctx, auth_tag.len, auth_tag.data,
497 plaintext_bytes_written, plaintext.data,
502 HARDENED_TRY(clear_key_if_sideloaded(internal_ctx.key));