implemented append mode for xcbc, testcase
[strongswan.git] / src / charon / plugins / unit_tester / tests / test_aes.c
index 22e8e25..06e891d 100644 (file)
@@ -13,6 +13,7 @@
  * for more details.
  */
 
+#include <daemon.h>
 #include <library.h>
 #include <utils/mutex.h>
 
@@ -166,3 +167,301 @@ bool test_aes128()
        }
        return TRUE;
 }
+
+/**
+ * run a single xcbc test for prf and signer
+ */
+static bool do_xcbc_test(u_int8_t *key, size_t keylen, u_int8_t *mac,
+                                                u_int8_t *plain, size_t len)
+{
+       signer_t *signer;
+       prf_t *prf;
+       u_int8_t res[16];
+       
+       prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
+       if (!prf)
+       {
+               return FALSE;
+       }
+       prf->set_key(prf, chunk_create(key, keylen));
+       prf->get_bytes(prf, chunk_create(plain, len), res);
+       if (!memeq(res, mac, 16))
+       {
+               DBG1(DBG_CFG, "expected %b\ngot %b", mac, 16, res, 16);
+               prf->destroy(prf);
+               return FALSE;
+       }
+       prf->destroy(prf);
+       
+       signer = lib->crypto->create_signer(lib->crypto, AUTH_AES_XCBC_96);
+       if (!signer)
+       {
+               return FALSE;
+       }
+       signer->set_key(signer, chunk_create(key, keylen));
+       if (!signer->verify_signature(signer, chunk_create(plain, len),
+                                                                 chunk_create(mac, 12)))
+       {
+               return FALSE;
+       }
+       signer->destroy(signer);
+       return TRUE;
+}
+
+
+/*******************************************************************************
+ * AES_XCBC mac test
+ ******************************************************************************/
+bool test_aes_xcbc()
+{
+       /*  Vectors from RFC 3566 */
+
+       /* Test Case #1   : AES-XCBC-MAC-96 with 0-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : <empty string>
+        * AES-XCBC-MAC   : 75f0251d528ac01c4573dfd584d79f29
+        * AES-XCBC-MAC-96: 75f0251d528ac01c4573dfd5
+        */
+       u_char key1[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain1[] = {
+       };
+       u_char mac1[] = {
+               0x75,0xf0,0x25,0x1d,0x52,0x8a,0xc0,0x1c,
+               0x45,0x73,0xdf,0xd5,0x84,0xd7,0x9f,0x29
+       };
+       if (!do_xcbc_test(key1, 16,  mac1, plain1, sizeof(plain1)))
+       {
+               return FALSE;
+       }
+       
+       /*
+        * Test Case #2   : AES-XCBC-MAC-96 with 3-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 000102
+        * AES-XCBC-MAC   : 5b376580ae2f19afe7219ceef172756f
+        * AES-XCBC-MAC-96: 5b376580ae2f19afe7219cee
+        */
+       u_char key2[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain2[] = {
+               0x00,0x01,0x02
+       };
+       u_char mac2[] = {
+               0x5b,0x37,0x65,0x80,0xae,0x2f,0x19,0xaf,
+               0xe7,0x21,0x9c,0xee,0xf1,0x72,0x75,0x6f
+       };
+       if (!do_xcbc_test(key2, 16,  mac2, plain2, sizeof(plain2)))
+       {
+               return FALSE;
+       }
+
+       /* Test Case #3   : AES-XCBC-MAC-96 with 16-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 000102030405060708090a0b0c0d0e0f
+        * AES-XCBC-MAC   : d2a246fa349b68a79998a4394ff7a263
+        * AES-XCBC-MAC-96: d2a246fa349b68a79998a439
+        */
+       u_char key3[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain3[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char mac3[] = {
+               0xd2,0xa2,0x46,0xfa,0x34,0x9b,0x68,0xa7,
+               0x99,0x98,0xa4,0x39,0x4f,0xf7,0xa2,0x63
+       };
+       if (!do_xcbc_test(key3, 16,  mac3, plain3, sizeof(plain3)))
+       {
+               return FALSE;
+       }
+
+       /* Test Case #4   : AES-XCBC-MAC-96 with 20-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 000102030405060708090a0b0c0d0e0f10111213
+        * AES-XCBC-MAC   : 47f51b4564966215b8985c63055ed308
+        * AES-XCBC-MAC-96: 47f51b4564966215b8985c63
+        */
+       u_char key4[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain4[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13
+       };
+       u_char mac4[] = {
+               0x47,0xf5,0x1b,0x45,0x64,0x96,0x62,0x15,
+               0xb8,0x98,0x5c,0x63,0x05,0x5e,0xd3,0x08
+       };
+       if (!do_xcbc_test(key4, 16,  mac4, plain4, sizeof(plain4)))
+       {
+               return FALSE;
+       }
+
+       /* Test Case #5   : AES-XCBC-MAC-96 with 32-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 000102030405060708090a0b0c0d0e0f10111213141516171819
+        *                      1a1b1c1d1e1f
+        * AES-XCBC-MAC   : f54f0ec8d2b9f3d36807734bd5283fd4
+        * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
+        */
+       u_char key5[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain5[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+               0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+       };
+       u_char mac5[] = {
+               0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
+               0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
+       };
+       if (!do_xcbc_test(key5, 16,  mac5, plain5, sizeof(plain5)))
+       {
+               return FALSE;
+       }
+       
+       /* Test Case #7   : AES-XCBC-MAC-96 with 1000-byte input
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 00000000000000000000 ... 00000000000000000000
+        *                  [1000 bytes]
+        * AES-XCBC-MAC   : f0dafee895db30253761103b5d84528f
+        * AES-XCBC-MAC-96: f0dafee895db30253761103b
+        */
+       u_char key7[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain7[1000];
+       memset(plain7, 0, 1000);
+       u_char mac7[] = {
+               0xf0,0xda,0xfe,0xe8,0x95,0xdb,0x30,0x25,
+               0x37,0x61,0x10,0x3b,0x5d,0x84,0x52,0x8f
+       };
+       if (!do_xcbc_test(key7, 16, mac7, plain7, sizeof(plain7)))
+       {
+               return FALSE;
+       }
+       
+       /* variable key test, RFC4434 */
+       
+       /* Test Case AES-XCBC-PRF-128 with 20-byte input
+        * Key        : 00010203040506070809
+        * Message    : 000102030405060708090a0b0c0d0e0f10111213
+        * PRF Output : 0fa087af7d866e7653434e602fdde835
+        */
+       u_char key8[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,
+       };
+       u_char plain8[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13
+       };
+       u_char mac8[] = {
+               0x0f,0xa0,0x87,0xaf,0x7d,0x86,0x6e,0x76,
+               0x53,0x43,0x4e,0x60,0x2f,0xdd,0xe8,0x35
+       };
+       if (!do_xcbc_test(key8, 10, mac8, plain8, sizeof(plain8)))
+       {
+               return FALSE;
+       }
+
+       /* Test Case AES-XCBC-PRF-128 with 20-byte input
+        * Key        : 000102030405060708090a0b0c0d0e0fedcb
+        * Message    : 000102030405060708090a0b0c0d0e0f10111213
+        * PRF Output : 8cd3c93ae598a9803006ffb67c40e9e4
+        */
+       u_char key9[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0xed,0xcb
+       };
+       u_char plain9[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13
+       };
+       u_char mac9[] = {
+               0x8c,0xd3,0xc9,0x3a,0xe5,0x98,0xa9,0x80,
+               0x30,0x06,0xff,0xb6,0x7c,0x40,0xe9,0xe4
+       };
+       if (!do_xcbc_test(key9, 18, mac9, plain9, sizeof(plain9)))
+       {
+               return FALSE;
+       }
+       
+       
+       /* Test Case #10  : AES-XCBC-MAC-96 with 32-byte input using append mode
+        * Key (K)        : 000102030405060708090a0b0c0d0e0f
+        * Message (M)    : 000102030405060708090a0b0c0d0e0f10111213141516171819
+        *                      1a1b1c1d1e1f
+        * AES-XCBC-MAC   : f54f0ec8d2b9f3d36807734bd5283fd4
+        * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
+        */
+       u_char key10[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+       };
+       u_char plain10[] = {
+               0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+               0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+       };
+       u_char mac10[] = {
+               0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
+               0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
+       };
+       int i;
+       prf_t *prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
+       u_char res[16];
+       if (!prf)
+       {
+               return FALSE;
+       }
+       prf->set_key(prf, chunk_create(key10, sizeof(key10)));
+       for (i = 0; i < 4; i++)
+       {       /* bytes 0 - 3, 1 byte at once */
+               prf->get_bytes(prf, chunk_create(plain10 + i, 1), NULL);
+       }
+       for (i = 4; i < 5; i+=8)
+       {       /* bytes 4 - 11, at once */
+               prf->get_bytes(prf, chunk_create(plain10 + i, 8), NULL);
+       }
+       for (i = 12; i < 24; i+=4)
+       {       /* bytes 12 - 23, in blocks of 4 */
+               prf->get_bytes(prf, chunk_create(plain10 + i, 4), NULL);
+       }
+       for (i = 0; i < 4; i++)
+       {       /* 4 zero blobs */
+               prf->get_bytes(prf, chunk_create(NULL, 0), NULL);
+       }
+       for (i = 24; i < 25; i+=8)
+       {       /* bytes 24 - 32, at once */
+               prf->get_bytes(prf, chunk_create(plain10 + i, 8), res);
+       }
+       if (!memeq(res, mac10, 16))
+       {
+               DBG1(DBG_CFG, "expected %b\ngot %b", mac10, 16, res, 16);
+               prf->destroy(prf);
+               return FALSE;
+       }
+       prf->destroy(prf);
+       
+       return TRUE; 
+}
+