Skip to content

Commit 75ca548

Browse files
committed
Implement AES-CTS in wolfCrypt
1 parent 6761dbb commit 75ca548

6 files changed

Lines changed: 566 additions & 11 deletions

File tree

configure.ac

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5438,6 +5438,22 @@ AC_ARG_ENABLE([xts],
54385438
[ ENABLED_AESXTS=$enableval ]
54395439
)
54405440

5441+
# AES-CTS
5442+
AC_ARG_ENABLE([aescts],
5443+
[AS_HELP_STRING([--enable-aescts],[Enable AES CTS (default: disabled)])],
5444+
[ ENABLED_AESCTS=$enableval ],
5445+
[ ENABLED_AESCTS=no ]
5446+
)
5447+
5448+
if test "$ENABLED_AESCTS" = "yes"
5449+
then
5450+
if test "$ENABLED_AESCBC" = "no"
5451+
then
5452+
AC_MSG_ERROR([AES CTS requires AES CBC.])
5453+
fi
5454+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_CTS"
5455+
fi
5456+
54415457
# Web Server Build
54425458
AC_ARG_ENABLE([webserver],
54435459
[AS_HELP_STRING([--enable-webserver],[Enable Web Server (default: disabled)])],

tests/api/test_aes.c

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,230 @@ int test_wc_AesCbcEncryptDecrypt(void)
263263
return EXPECT_RESULT();
264264
} /* END test_wc_AesCbcEncryptDecrypt */
265265

266+
/*******************************************************************************
267+
* AES-CTS
268+
******************************************************************************/
269+
270+
int test_wc_AesCtsEncryptDecrypt(void)
271+
{
272+
EXPECT_DECLS;
273+
#if !defined(NO_AES) && defined(WOLFSSL_AES_CTS) && \
274+
defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_128)
275+
/* Test vectors taken form RFC3962 Appendix B */
276+
struct {
277+
const char* input;
278+
const char* output;
279+
size_t inLen;
280+
size_t outLen;
281+
} vects[] = {
282+
{
283+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
284+
"\x20",
285+
"\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
286+
"\x97",
287+
17, 17
288+
},
289+
{
290+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
291+
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20",
292+
"\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
293+
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
294+
31, 31
295+
},
296+
{
297+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
298+
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43",
299+
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
300+
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
301+
32, 32
302+
},
303+
{
304+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
305+
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
306+
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c",
307+
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
308+
"\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
309+
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
310+
47, 47
311+
},
312+
{
313+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
314+
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
315+
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20",
316+
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
317+
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
318+
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
319+
48, 48
320+
},
321+
{
322+
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
323+
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
324+
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20"
325+
"\x61\x6e\x64\x20\x77\x6f\x6e\x74\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
326+
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
327+
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
328+
"\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
329+
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
330+
64, 64
331+
}
332+
};
333+
byte keyBytes[AES_128_KEY_SIZE] = {
334+
0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
335+
0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
336+
};
337+
byte tmp[64]; /* Largest vector size */
338+
size_t i;
339+
byte iv[AES_IV_SIZE]; /* All-zero IV for all cases */
340+
341+
XMEMSET(iv, 0, sizeof(iv));
342+
for (i = 0; i < XELEM_CNT(vects) && EXPECT_SUCCESS(); i++) {
343+
/* One-shot encrypt */
344+
XMEMSET(tmp, 0, sizeof(tmp));
345+
ExpectIntEQ(wc_AesCtsEncrypt(keyBytes, sizeof(keyBytes), tmp,
346+
(const byte*)vects[i].input, (word32)vects[i].inLen, iv), 0);
347+
ExpectBufEQ(tmp, vects[i].output, vects[i].outLen);
348+
XMEMSET(tmp, 0, sizeof(tmp));
349+
ExpectIntEQ(wc_AesCtsDecrypt(keyBytes, sizeof(keyBytes), tmp,
350+
(const byte*)vects[i].output, (word32)vects[i].outLen, iv), 0);
351+
ExpectBufEQ(tmp, vects[i].input, vects[i].inLen);
352+
}
353+
/* Execute all branches */
354+
{
355+
Aes* aes = NULL;
356+
int result_code = 0;
357+
const byte* in = (const byte*)vects[5].input;
358+
byte* out = tmp;
359+
word32 outSz = (word32)vects[5].outLen;
360+
word32 remSz = (word32)vects[5].outLen;
361+
362+
XMEMSET(tmp, 0, sizeof(tmp));
363+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
364+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
365+
AES_ENCRYPTION), 0);
366+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 1), 0);
367+
in += 1; out += outSz; remSz -= outSz; outSz = remSz;
368+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 31), 0);
369+
in += 31; out += outSz; remSz -= outSz; outSz = remSz;
370+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 32), 0);
371+
in += 32; out += outSz; remSz -= outSz; outSz = remSz;
372+
ExpectIntEQ(wc_AesCtsEncryptFinal(aes, out, &outSz), 0);
373+
remSz -= outSz;
374+
ExpectIntEQ(remSz, 0);
375+
ExpectBufEQ(tmp, vects[5].output, vects[5].outLen);
376+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
377+
}
378+
{
379+
Aes* aes = NULL;
380+
int result_code = 0;
381+
const byte* in = (const byte*)vects[5].input;
382+
byte* out = tmp;
383+
word32 outSz = (word32)vects[5].outLen;
384+
word32 remSz = (word32)vects[5].outLen;
385+
386+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
387+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
388+
AES_ENCRYPTION), 0);
389+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 1), 0);
390+
in += 1; out += outSz; remSz -= outSz; outSz = remSz;
391+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 63), 0);
392+
in += 63; out += outSz; remSz -= outSz; outSz = remSz;
393+
ExpectIntEQ(wc_AesCtsEncryptFinal(aes, out, &outSz), 0);
394+
remSz -= outSz;
395+
ExpectIntEQ(remSz, 0);
396+
ExpectBufEQ(tmp, vects[5].output, vects[5].outLen);
397+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
398+
}
399+
{
400+
Aes* aes = NULL;
401+
int result_code = 0;
402+
const byte* in = (const byte*)vects[2].input;
403+
byte* out = tmp;
404+
word32 outSz = (word32)vects[2].outLen;
405+
word32 remSz = (word32)vects[2].outLen;
406+
407+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
408+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
409+
AES_ENCRYPTION), 0);
410+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 16), 0);
411+
in += 16; out += outSz; remSz -= outSz; outSz = remSz;
412+
ExpectIntEQ(wc_AesCtsEncryptUpdate(aes, out, &outSz, in, 16), 0);
413+
in += 16; out += outSz; remSz -= outSz; outSz = remSz;
414+
ExpectIntEQ(wc_AesCtsEncryptFinal(aes, out, &outSz), 0);
415+
remSz -= outSz;
416+
ExpectIntEQ(remSz, 0);
417+
ExpectBufEQ(tmp, vects[2].output, vects[2].outLen);
418+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
419+
}
420+
{
421+
Aes* aes = NULL;
422+
int result_code = 0;
423+
const byte* in = (const byte*)vects[5].output;
424+
byte* out = tmp;
425+
word32 outSz = (word32)vects[5].inLen;
426+
word32 remSz = (word32)vects[5].inLen;
427+
428+
XMEMSET(tmp, 0, sizeof(tmp));
429+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
430+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
431+
AES_DECRYPTION), 0);
432+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 1), 0);
433+
in += 1; out += outSz; remSz -= outSz; outSz = remSz;
434+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 31), 0);
435+
in += 31; out += outSz; remSz -= outSz; outSz = remSz;
436+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 32), 0);
437+
in += 32; out += outSz; remSz -= outSz; outSz = remSz;
438+
ExpectIntEQ(wc_AesCtsDecryptFinal(aes, out, &outSz), 0);
439+
remSz -= outSz;
440+
ExpectIntEQ(remSz, 0);
441+
ExpectBufEQ(tmp, vects[5].input, vects[5].inLen);
442+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
443+
}
444+
{
445+
Aes* aes = NULL;
446+
int result_code = 0;
447+
const byte* in = (const byte*)vects[5].output;
448+
byte* out = tmp;
449+
word32 outSz = (word32)vects[5].inLen;
450+
word32 remSz = (word32)vects[5].inLen;
451+
452+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
453+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
454+
AES_DECRYPTION), 0);
455+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 1), 0);
456+
in += 1; out += outSz; remSz -= outSz; outSz = remSz;
457+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 63), 0);
458+
in += 63; out += outSz; remSz -= outSz; outSz = remSz;
459+
ExpectIntEQ(wc_AesCtsDecryptFinal(aes, out, &outSz), 0);
460+
remSz -= outSz;
461+
ExpectIntEQ(remSz, 0);
462+
ExpectBufEQ(tmp, vects[5].input, vects[5].inLen);
463+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
464+
}
465+
{
466+
Aes* aes = NULL;
467+
int result_code = 0;
468+
const byte* in = (const byte*)vects[2].output;
469+
byte* out = tmp;
470+
word32 outSz = (word32)vects[2].inLen;
471+
word32 remSz = (word32)vects[2].inLen;
472+
473+
ExpectNotNull(aes = wc_AesNew(NULL, INVALID_DEVID, &result_code));
474+
ExpectIntEQ(wc_AesSetKey(aes, keyBytes, sizeof(keyBytes), iv,
475+
AES_DECRYPTION), 0);
476+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 16), 0);
477+
in += 16; out += outSz; remSz -= outSz; outSz = remSz;
478+
ExpectIntEQ(wc_AesCtsDecryptUpdate(aes, out, &outSz, in, 16), 0);
479+
in += 16; out += outSz; remSz -= outSz; outSz = remSz;
480+
ExpectIntEQ(wc_AesCtsDecryptFinal(aes, out, &outSz), 0);
481+
remSz -= outSz;
482+
ExpectIntEQ(remSz, 0);
483+
ExpectBufEQ(tmp, vects[2].input, vects[2].inLen);
484+
ExpectIntEQ(wc_AesDelete(aes, &aes), 0);
485+
}
486+
#endif
487+
return EXPECT_RESULT();
488+
}
489+
266490
/*******************************************************************************
267491
* AES-CTR
268492
******************************************************************************/

tests/api/test_aes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
int test_wc_AesSetKey(void);
2828
int test_wc_AesSetIV(void);
2929
int test_wc_AesCbcEncryptDecrypt(void);
30+
int test_wc_AesCtsEncryptDecrypt(void);
3031
int test_wc_AesCtrEncryptDecrypt(void);
3132
int test_wc_AesGcmSetKey(void);
3233
int test_wc_AesGcmEncryptDecrypt(void);
@@ -48,6 +49,7 @@ int test_wc_GmacUpdate(void);
4849
TEST_DECL_GROUP("aes", test_wc_AesSetKey), \
4950
TEST_DECL_GROUP("aes", test_wc_AesSetIV), \
5051
TEST_DECL_GROUP("aes", test_wc_AesCbcEncryptDecrypt), \
52+
TEST_DECL_GROUP("aes", test_wc_AesCtsEncryptDecrypt), \
5153
TEST_DECL_GROUP("aes", test_wc_AesCtrEncryptDecrypt), \
5254
TEST_DECL_GROUP("aes", test_wc_AesGcmSetKey), \
5355
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt), \

0 commit comments

Comments
 (0)