Skip to content

Commit

Permalink
Merge pull request #799 from LedgerHQ/issue-2763
Browse files Browse the repository at this point in the history
cx_aes_siv: Add new function to reset AES hw copro
  • Loading branch information
jarevalo-ledger authored and abonnaudet-ledger committed Oct 21, 2024
2 parents 50b1695 + a305b6b commit a82cdbb
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 11 deletions.
1 change: 1 addition & 0 deletions include/cx_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,4 @@
#define _NR_cx_cmac_start 0x8d
#define _NR_cx_cmac_update 0x8e
#define _NR_cx_cmac_finish 0x8f
#define _NR_cx_aes_siv_reset 0x90
2 changes: 1 addition & 1 deletion include/ox_aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ cx_aes_set_key_hw(const cx_aes_key_t *key PLENGTH(sizeof(cx_aes_key_t)), uint32_
/**
* @brief Resets the AES context.
*/
SYSCALL void cx_aes_reset_hw(void);
SYSCALL cx_err_t cx_aes_reset_hw(void);

/**
* @brief Encrypts or decrypts a block with AES.
Expand Down
1 change: 1 addition & 0 deletions lib_cxng/cx.export
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,4 @@ cx_cipher_reset
cx_cmac_start
cx_cmac_update
cx_cmac_finish
cx_aes_siv_reset
11 changes: 11 additions & 0 deletions lib_cxng/include/lcx_aes_siv.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ typedef struct _cx_aes_siv_context {
*/
WARN_UNUSED_RESULT cx_err_t cx_aes_siv_init(cx_aes_siv_context_t *ctx);

/**
* @brief Reset the AES-SIV context and HW used.
* @details The cipher context must be initialized beforehand.
* This function must be called after calls to #cx_aes_siv_finish or
* #cx_aes_siv_update.
*
* @param[in] ctx Pointer to the AES-SIV context.
* @return Error code.
*/
WARN_UNUSED_RESULT cx_err_t cx_aes_siv_reset(cx_aes_siv_context_t *ctx);

/**
* @brief Sets the key to compute AES-SIV.
*
Expand Down
11 changes: 7 additions & 4 deletions lib_cxng/src/cx_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,24 @@ cx_err_t cx_aes_init_key_no_throw(const uint8_t *raw_key, size_t key_len, cx_aes
cx_err_t cx_aes_enc_block(const cx_aes_key_t *key, const uint8_t *inblock, uint8_t *outblock)
{
cx_err_t error;
cx_err_t err_reset = CX_INTERNAL_ERROR;
CX_CHECK(cx_aes_set_key_hw(key, CX_ENCRYPT));
CX_CHECK(cx_aes_block_hw(inblock, outblock));
cx_aes_reset_hw();
end:
return error;
err_reset = cx_aes_reset_hw();
return error == CX_OK ? err_reset : error;
}

cx_err_t cx_aes_dec_block(const cx_aes_key_t *key, const uint8_t *inblock, uint8_t *outblock)
{
cx_err_t error;
cx_err_t err_reset = CX_INTERNAL_ERROR;
CX_CHECK(cx_aes_set_key_hw(key, CX_ENCRYPT));
CX_CHECK(cx_aes_set_key_hw(key, CX_DECRYPT));
CX_CHECK(cx_aes_block_hw(inblock, outblock));
cx_aes_reset_hw();
end:
return error;
err_reset = cx_aes_reset_hw();
return error == CX_OK ? err_reset : error;
}

cx_err_t cx_aes_iv_no_throw(const cx_aes_key_t *key,
Expand Down
23 changes: 20 additions & 3 deletions lib_cxng/src/cx_aes_siv.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ cx_err_t cx_aes_siv_init(cx_aes_siv_context_t *ctx)
return error;
}

cx_err_t cx_aes_siv_reset(cx_aes_siv_context_t *ctx)
{
cx_err_t error = CX_INVALID_PARAMETER_VALUE;
if (ctx->cipher_ctx == NULL) {
goto end;
}
CX_CHECK(ctx->cipher_ctx->cipher_info->base->ctx_reset());
cx_cipher_reset(ctx->cipher_ctx);

end:
return error;
}

cx_err_t cx_aes_siv_set_key(cx_aes_siv_context_t *ctx, const uint8_t *key, size_t key_bitlen)
{
// AES SIV uses two keys of either 128, 192 or 256 bits each
Expand Down Expand Up @@ -156,12 +169,14 @@ cx_err_t cx_aes_siv_encrypt(cx_aes_siv_context_t *ctx,
uint8_t *tag)
{
cx_err_t error;
cx_err_t err_reset = CX_INTERNAL_ERROR;
CX_CHECK(cx_aes_siv_start(ctx, CX_ENCRYPT, NULL, 0));
CX_CHECK(cx_aes_siv_update_aad(ctx, aad, aad_len));
CX_CHECK(cx_aes_siv_finish(ctx, input, in_len, tag));
CX_CHECK(cx_aes_siv_update(ctx, input, output, in_len));
end:
return error;
err_reset = cx_aes_siv_reset(ctx);
return error == CX_OK ? err_reset : error;
}

cx_err_t cx_aes_siv_decrypt(cx_aes_siv_context_t *ctx,
Expand All @@ -173,14 +188,16 @@ cx_err_t cx_aes_siv_decrypt(cx_aes_siv_context_t *ctx,
uint8_t *tag)
{
cx_err_t error;
cx_err_t err_reset = CX_INTERNAL_ERROR;
CX_CHECK(cx_aes_siv_start(ctx, CX_DECRYPT, tag, CX_AES_BLOCK_SIZE));
CX_CHECK(cx_aes_siv_update(ctx, input, output, in_len));
cx_cipher_reset(ctx->cipher_ctx);
CX_CHECK(cx_aes_siv_reset(ctx));
CX_CHECK(cx_aes_siv_update_aad(ctx, aad, aad_len));
CX_CHECK(cx_aes_siv_finish(ctx, output, in_len, tag));

end:
return error;
err_reset = cx_aes_siv_reset(ctx);
return error == CX_OK ? err_reset : error;
}

#endif // HAVE_AES && HAVE_CMAC
Expand Down
2 changes: 1 addition & 1 deletion lib_cxng/src/cx_cipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern const cx_cipher_info_t cx_aes_256_info;
/** HW support */
WARN_UNUSED_RESULT cx_err_t cx_aes_set_key_hw(const cx_aes_key_t *keys, uint32_t mode);
WARN_UNUSED_RESULT cx_err_t cx_aes_block_hw(const uint8_t *inblock, uint8_t *outblock);
void cx_aes_reset_hw(void);
WARN_UNUSED_RESULT cx_err_t cx_aes_reset_hw(void);
#endif // HAVE_AES

#endif /* CX_CIPHER_H */
1 change: 1 addition & 0 deletions src/cx_stubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ CX_TRAMPOLINE _NR_cx_cipher_reset cx_cipher_reset
CX_TRAMPOLINE _NR_cx_cmac_start cx_cmac_start
CX_TRAMPOLINE _NR_cx_cmac_update cx_cmac_update
CX_TRAMPOLINE _NR_cx_cmac_finish cx_cmac_finish
CX_TRAMPOLINE _NR_cx_aes_siv_reset cx_aes_siv_reset

.thumb_func
cx_trampoline_helper:
Expand Down
4 changes: 2 additions & 2 deletions src/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ cx_err_t cx_aes_set_key_hw(const cx_aes_key_t *keys, uint32_t mode)
return SVC_cx_call(SYSCALL_cx_aes_set_key_hw_ID, parameters);
}

void cx_aes_reset_hw(void)
cx_err_t cx_aes_reset_hw(void)
{
unsigned int parameters[2];
parameters[1] = 0;
SVC_cx_call(SYSCALL_cx_aes_reset_hw_ID, parameters);
return SVC_cx_call(SYSCALL_cx_aes_reset_hw_ID, parameters);
}

cx_err_t cx_aes_block_hw(const unsigned char *inblock, unsigned char *outblock)
Expand Down

0 comments on commit a82cdbb

Please sign in to comment.