5 #include "sw/device/lib/crypto/impl/aes_kwp/aes_kwp.h"
14 #include "sw/device/lib/crypto/drivers/aes.h"
15 #include "sw/device/lib/crypto/impl/status.h"
18 #define MODULE_ID MAKE_MODULE_ID('k', 'w', 'p')
22 kSemiblockBytes = kAesBlockNumBytes / 2,
24 kSemiblockWords = kSemiblockBytes /
sizeof(uint32_t),
28 const size_t plaintext_len, uint32_t *ciphertext) {
30 if (plaintext_len > UINT32_MAX || plaintext_len == 0) {
31 return OTCRYPTO_BAD_ARGS;
36 size_t plaintext_semiblocks =
ceil_div(plaintext_len, kSemiblockBytes);
37 size_t pad_len = kSemiblockBytes * plaintext_semiblocks - plaintext_len;
39 if (plaintext_semiblocks < 2) {
41 return OTCRYPTO_BAD_ARGS;
45 HARDENED_TRY(aes_encrypt_begin(kek, NULL));
54 .data = {0xa65959a6, __builtin_bswap32(plaintext_len), 0, 0},
58 size_t plaintext_words =
ceil_div(plaintext_len,
sizeof(uint32_t));
60 hardened_memcpy(ciphertext + kSemiblockWords, plaintext, plaintext_words);
61 unsigned char *pad_start =
62 ((
unsigned char *)ciphertext) + kSemiblockBytes + plaintext_len;
63 memset(pad_start, 0, pad_len);
66 for (
size_t j = 0; j < 6; j++) {
67 for (
size_t i = 1; i <= plaintext_semiblocks; i++) {
70 ciphertext + i * kSemiblockWords, kSemiblockWords);
71 HARDENED_TRY(aes_update(NULL, &block));
72 HARDENED_TRY(aes_update(&block, NULL));
76 block.data[0] ^= __builtin_bswap32((uint32_t)(t >> 32));
77 block.data[1] ^= __builtin_bswap32((uint32_t)(t & UINT32_MAX));
82 block.data + kSemiblockWords, kSemiblockWords);
93 uint32_t *plaintext) {
96 if (ciphertext_len > UINT32_MAX || ciphertext_len == 0 ||
97 ciphertext_len % kSemiblockBytes != 0) {
98 return OTCRYPTO_BAD_ARGS;
102 size_t ciphertext_semiblocks = ciphertext_len / kSemiblockBytes;
104 if (ciphertext_semiblocks < 3) {
106 return OTCRYPTO_BAD_ARGS;
110 HARDENED_TRY(aes_decrypt_begin(kek, NULL));
118 .data = {ciphertext[0], ciphertext[1], 0, 0},
122 uint32_t r[(ciphertext_semiblocks - 1) * kSemiblockWords];
125 uint64_t t = 6 * ((uint64_t)ciphertext_semiblocks - 1);
126 for (
size_t j = 0; j < 6; j++) {
127 for (
size_t i = ciphertext_semiblocks - 1; 1 <= i; i--) {
129 block.data[0] ^= __builtin_bswap32((uint32_t)(t >> 32));
130 block.data[1] ^= __builtin_bswap32((uint32_t)(t & UINT32_MAX));
135 r + (i - 1) * kSemiblockWords, kSemiblockWords);
136 HARDENED_TRY(aes_update(NULL, &block));
137 HARDENED_TRY(aes_update(&block, NULL));
141 block.data + kSemiblockWords, kSemiblockWords);
146 if (block.data[0] != 0xa65959a6) {
152 size_t plaintext_len = __builtin_bswap32(block.data[1]);
154 kSemiblockBytes * (ciphertext_semiblocks - 1) - plaintext_len;
157 if (pad_len >= kSemiblockBytes) {
166 uint8_t exp_pad[pad_len];
167 memset(exp_pad, 0, pad_len);
168 unsigned char *pad_start = ((
unsigned char *)r) + plaintext_len;
169 if (
memcmp(pad_start, exp_pad, pad_len) != 0) {
176 size_t plaintext_words =
ceil_div(plaintext_len,
sizeof(uint32_t));