5 #include "sw/device/tests/crypto/aes_gcm_testutils.h"
9 #include "sw/device/lib/base/status.h"
10 #include "sw/device/lib/crypto/impl/integrity.h"
11 #include "sw/device/lib/crypto/impl/keyblob.h"
15 #include "sw/device/lib/testing/profile.h"
16 #include "sw/device/lib/testing/test_framework/check.h"
18 #define MODULE_ID MAKE_MODULE_ID('a', 'g', 't')
23 static const uint32_t kKeyMask[8] = {
24 0x01234567, 0x89abcdef, 0x00010203, 0x04050607,
25 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617,
32 kStreamingAadChunkBytes = 10,
36 kStreamingMessageChunkBytes = 20,
43 switch (tag_len_bytes) {
45 return kOtcryptoAesGcmTagLen128;
47 return kOtcryptoAesGcmTagLen96;
49 return kOtcryptoAesGcmTagLen64;
51 return kOtcryptoAesGcmTagLen32;
78 size_t *output_bytes_written) {
81 size_t num_chunks =
ceil_div(aad.len, kStreamingAadChunkBytes);
82 for (
size_t i = 0; i < num_chunks; i++) {
83 size_t offset = i * kStreamingAadChunkBytes;
84 size_t chunk_len = kStreamingAadChunkBytes;
85 if (offset + chunk_len > aad.len) {
86 chunk_len = aad.len - offset;
89 .data = aad.data + offset,
98 *output_bytes_written = 0;
100 size_t num_chunks =
ceil_div(input.len, kStreamingMessageChunkBytes);
101 for (
size_t i = 0; i < num_chunks; i++) {
102 size_t offset = i * kStreamingMessageChunkBytes;
103 size_t chunk_len = kStreamingMessageChunkBytes;
104 if (offset + chunk_len > input.len) {
105 chunk_len = input.len - offset;
108 .data = input.data + offset,
112 .data = output.data + *output_bytes_written,
113 .len = output.len - *output_bytes_written,
115 size_t bytes_written_for_chunk = 0;
117 ctx, input_chunk, output_with_offset, &bytes_written_for_chunk));
118 *output_bytes_written += bytes_written_for_chunk;
128 .version = kOtcryptoLibVersion1,
129 .key_mode = kOtcryptoKeyModeAesGcm,
130 .key_length =
test->key_len *
sizeof(uint32_t),
132 .security_level = kOtcryptoKeySecurityLevelLow,
136 uint32_t keyblob[keyblob_num_words(config)];
137 TRY(keyblob_from_key_and_mask(
test->key, kKeyMask, config, keyblob));
142 .keyblob_length =
sizeof(keyblob),
148 key.checksum = integrity_blinded_checksum(&key);
150 size_t iv_num_words =
151 (
test->iv_len +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
152 uint32_t iv_data[iv_num_words];
159 .data =
test->plaintext,
160 .len =
test->plaintext_len,
164 .len =
test->aad_len,
167 size_t tag_num_words =
168 (
test->tag_len +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
169 uint32_t actual_tag_data[tag_num_words];
171 .data = actual_tag_data,
172 .len = tag_num_words,
175 size_t ciphertext_blocks =
ceil_div(
test->plaintext_len, kAesBlockNumBytes);
176 uint8_t actual_ciphertext_data[ciphertext_blocks * kAesBlockNumBytes];
178 .data = actual_ciphertext_data,
179 .len =
test->plaintext_len,
185 uint64_t t_start = profile_start();
188 size_t ciphertext_bytes_written;
189 TRY(stream_gcm(&ctx, aad, plaintext, actual_ciphertext,
190 &ciphertext_bytes_written));
192 .data = actual_ciphertext.data + ciphertext_bytes_written,
193 .len =
test->plaintext_len - ciphertext_bytes_written,
196 &ciphertext_bytes_written, actual_tag));
197 *cycles = profile_end(t_start);
200 uint64_t t_start = profile_start();
202 &key, plaintext, iv, aad, tag_len, actual_ciphertext, actual_tag);
203 *cycles = profile_end(t_start);
210 if (
test->plaintext_len > 0) {
211 TRY_CHECK_ARRAYS_EQ(actual_ciphertext_data,
test->ciphertext,
212 test->plaintext_len);
214 TRY_CHECK_ARRAYS_EQ((
unsigned char *)actual_tag_data,
test->tag,
225 .version = kOtcryptoLibVersion1,
226 .key_mode = kOtcryptoKeyModeAesGcm,
227 .key_length =
test->key_len *
sizeof(uint32_t),
229 .security_level = kOtcryptoKeySecurityLevelLow,
233 uint32_t keyblob[keyblob_num_words(config)];
234 TRY(keyblob_from_key_and_mask(
test->key, kKeyMask, config, keyblob));
239 .keyblob_length =
sizeof(keyblob),
245 key.checksum = integrity_blinded_checksum(&key);
247 size_t iv_num_words =
248 (
test->iv_len +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
249 uint32_t iv_data[iv_num_words];
256 .data =
test->ciphertext,
257 .len =
test->plaintext_len,
261 .len =
test->aad_len,
263 size_t tag_num_words =
264 (
test->tag_len +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
265 uint32_t tag_data[tag_num_words];
269 .len = tag_num_words,
272 size_t ciphertext_blocks =
ceil_div(
test->plaintext_len, kAesBlockNumBytes);
273 uint8_t actual_plaintext_data[ciphertext_blocks * kAesBlockNumBytes];
275 .data = actual_plaintext_data,
276 .len =
test->plaintext_len,
283 uint64_t t_start = profile_start();
285 size_t plaintext_bytes_written;
286 TRY(stream_gcm(&ctx, aad, ciphertext, actual_plaintext,
287 &plaintext_bytes_written));
289 .data = actual_plaintext.data + plaintext_bytes_written,
290 .len = actual_plaintext.len - plaintext_bytes_written,
292 size_t final_plaintext_bytes_written;
294 &final_plaintext_bytes_written,
296 *cycles = profile_end(t_start);
300 uint64_t t_start = profile_start();
302 &key, ciphertext, iv, aad, tag_len, tag, actual_plaintext, tag_valid);
303 *cycles = profile_end(t_start);
312 TRY_CHECK_ARRAYS_EQ(actual_plaintext_data,
test->plaintext,
313 test->plaintext_len);