//====================================================================== // // aes_tester.c // ------------ // Simple test sw for the aes core. Based on the NIST test cases. // Test cases taken from NIST SP 800-38A: // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf // // // Author: Joachim Strombergson // Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // - Neither the name of the NORDUnet nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // //====================================================================== #include #include #include #include #include #include "cryptech.h" //------------------------------------------------------------------ // Robs macros. Scary scary. //------------------------------------------------------------------ #define check(_expr_)\ do {\ if ((_expr_) != 0)\ printf("%s failed\n", #_expr_), 1;\ } while (0) #define set_and_check(_field_)\ do {\ printf("Setting %s\n", #_field_);\ check(tc_write(_field_, one, sizeof(one)));\ check(tc_read( _field_, res, sizeof(res)));\ if (memcmp(one, res, sizeof(one)))\ printf("MISMATCH\n");\ printf("\n");\ } while (0) //------------------------------------------------------------------ //------------------------------------------------------------------ void check_aes_access() { uint8_t name0[4], name1[4], version[4]; printf("Trying to read the aes core name\n"); check(tc_read(AES_ADDR_NAME0, name0, sizeof(name0))); check(tc_read(AES_ADDR_NAME1, name1, sizeof(name1))); check(tc_read(AES_ADDR_VERSION, version, sizeof(version))); printf("%4.4s%4.4s %4.4s\n\n", name0, name1, version); } //------------------------------------------------------------------ //------------------------------------------------------------------ void tc_w32(addr, data) { uint8_t w[4]; w[0] = data >> 24 & 0xff; w[1] = data >> 16 & 0xff; w[2] = data >> 8 & 0xff; w[3] = data & 0xff; tc_write(addr, w, 4); } //------------------------------------------------------------------ //------------------------------------------------------------------ uint32_t tc_r32(addr) { uint8_t w[4]; tc_read(addr, w, 4); return (uint32_t)((w[0] << 24) + (w[1] << 16) + (w[2] << 8) + w[3]); } //------------------------------------------------------------------ // dual_block_test //------------------------------------------------------------------ void dual_block_test(uint8_t keylength, uint32_t *key, uint32_t *block0, uint32_t *block1, uint32_t *expected) { } //------------------------------------------------------------------ // single_block_test // // Perform single block tests. //------------------------------------------------------------------ void single_block_test(uint32_t keylength, uint32_t *key, uint32_t *block, uint32_t *expected) { uint32_t enc_result[4]; uint32_t dec_result[4]; tc_w32(AES_ADDR_KEY0, key[0]); tc_w32(AES_ADDR_KEY1, key[1]); tc_w32(AES_ADDR_KEY2, key[2]); tc_w32(AES_ADDR_KEY3, key[3]); if (keylength == 256) { tc_w32(AES_ADDR_KEY0, key[4]); tc_w32(AES_ADDR_KEY1, key[5]); tc_w32(AES_ADDR_KEY2, key[6]); tc_w32(AES_ADDR_KEY3, key[7]); } tc_w32(AES_ADDR_BLOCK0, block[0]); tc_w32(AES_ADDR_BLOCK1, block[1]); tc_w32(AES_ADDR_BLOCK2, block[2]); tc_w32(AES_ADDR_BLOCK3, block[3]); // Single block encipher operation. if (keylength == 256) tc_w32(AES_ADDR_CONFIG, 0x00000003); else tc_w32(AES_ADDR_CONFIG, 0x00000001); tc_w32(AES_ADDR_CTRL, 0x00000001); tc_wait_ready(AES_ADDR_STATUS); enc_result[0] = tc_r32(AES_ADDR_RESULT0); enc_result[1] = tc_r32(AES_ADDR_RESULT1); enc_result[2] = tc_r32(AES_ADDR_RESULT2); enc_result[3] = tc_r32(AES_ADDR_RESULT3); tc_w32(AES_ADDR_BLOCK0, enc_result[0]); tc_w32(AES_ADDR_BLOCK1, enc_result[1]); tc_w32(AES_ADDR_BLOCK2, enc_result[2]); tc_w32(AES_ADDR_BLOCK3, enc_result[3]); // Single block decipher operation. if (keylength == 256) tc_w32(AES_ADDR_CONFIG, 0x00000002); else tc_w32(AES_ADDR_CONFIG, 0x00000000); tc_w32(AES_ADDR_CTRL, 0x00000001); tc_wait_ready(AES_ADDR_STATUS); dec_result[0] = tc_r32(AES_ADDR_RESULT0); dec_result[1] = tc_r32(AES_ADDR_RESULT1); dec_result[2] = tc_r32(AES_ADDR_RESULT2); dec_result[3] = tc_r32(AES_ADDR_RESULT3); printf("Generated cipher block:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", enc_result[0], enc_result[1], enc_result[2], enc_result[3]); printf("Expected cipher block:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", expected[0], expected[1], expected[2], expected[3]); printf("\n"); printf("Generated decipher block:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", dec_result[0], dec_result[1], dec_result[2], dec_result[3]); printf("Expected decipher block:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", block[0], block[1], block[2], block[3]); printf("\n"); } //------------------------------------------------------------------ // run_nist_tests() //------------------------------------------------------------------ void run_nist_tests() { uint32_t nist_aes128_key[4] = {0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c}; uint32_t nist_aes256_key[8] = {0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781, 0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4}; uint32_t nist_plaintext0[4] = {0x6bc1bee2, 0x2e409f96, 0xe93d7e11, 0x7393172a}; uint32_t nist_plaintext1[4] = {0xae2d8a57, 0x1e03ac9c, 0x9eb76fac, 0x45af8e51}; uint32_t nist_plaintext2[4] = {0x30c81c46, 0xa35ce411, 0xe5fbc119, 0x1a0a52ef}; uint32_t nist_plaintext3[4] = {0xf69f2445, 0xdf4f9b17, 0xad2b417b, 0xe66c3710}; uint32_t nist_ecb_128_enc_expected0[4] = {0x3ad77bb4, 0x0d7a3660, 0xa89ecaf3, 0x2466ef97}; uint32_t nist_ecb_128_enc_expected1[4] = {0xf5d3d585, 0x03b9699d, 0xe785895a, 0x96fdbaaf}; uint32_t nist_ecb_128_enc_expected2[4] = {0x43b1cd7f, 0x598ece23, 0x881b00e3, 0xed030688}; uint32_t nist_ecb_128_enc_expected3[4] = {0x7b0c785e, 0x27e8ad3f, 0x82232071, 0x04725dd4}; uint32_t nist_ecb_256_enc_expected0[4] = {0xf3eed1bd, 0xb5d2a03c, 0x064b5a7e, 0x3db181f8}; uint32_t nist_ecb_256_enc_expected1[4] = {0x591ccb10, 0xd410ed26, 0xdc5ba74a, 0x31362870}; uint32_t nist_ecb_256_enc_expected2[4] = {0xb6ed21b9, 0x9ca6f4f9, 0xf153e7b1, 0xbeafed1d}; uint32_t nist_ecb_256_enc_expected3[4] = {0x23304b7a, 0x39f9f3ff, 0x067d8d8f, 0x9e24ecc7}; printf("Running NIST single block test.\n"); single_block_test(128, &nist_aes128_key[0], &nist_plaintext0[0], &nist_ecb_128_enc_expected0[0]); single_block_test(128, &nist_aes128_key[0], &nist_plaintext1[0], &nist_ecb_128_enc_expected1[0]); single_block_test(128, &nist_aes128_key[0], &nist_plaintext2[0], &nist_ecb_128_enc_expected2[0]); single_block_test(128, &nist_aes128_key[0], &nist_plaintext3[0], &nist_ecb_128_enc_expected3[0]); single_block_test(256, &nist_aes256_key[0], &nist_plaintext0[0], &nist_ecb_256_enc_expected0[0]); single_block_test(256, &nist_aes256_key[0], &nist_plaintext1[0], &nist_ecb_256_enc_expected1[0]); single_block_test(256, &nist_aes256_key[0], &nist_plaintext2[0], &nist_ecb_256_enc_expected2[0]); single_block_test(256, &nist_aes256_key[0], &nist_plaintext3[0], &nist_ecb_256_enc_expected3[0]); } //------------------------------------------------------------------ //------------------------------------------------------------------ int main(int argc, char *argv[]) { check_aes_access(); tc_set_debug(1); run_nist_tests(); return 0; } //====================================================================== // EOF aes_tester.c //======================================================================