//====================================================================== // // modexp_tester.c // --------------- // Simple test sw for the modexp. // // // Author: Joachim Strombergson, Rob Austein, // 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" //------------------------------------------------------------------ // Global defines. //------------------------------------------------------------------ #define VERBOSE 0 #define CHECK_WRITE 0 //------------------------------------------------------------------ // Robs macros. Scary scary. //------------------------------------------------------------------ #define check(_expr_) \ do { \ if ((_expr_) != 0) { \ printf("%s failed\n", #_expr_); \ exit(1); \ } \ } while (0) //------------------------------------------------------------------ // tc_w32() // // Write 32-bit word to given address. //------------------------------------------------------------------ static void tc_w32(const off_t addr, const uint32_t data) { uint8_t w[4]; w[0] = data >> 24 & 0xff; w[1] = data >> 16 & 0xff; w[2] = data >> 8 & 0xff; w[3] = data & 0xff; check(tc_write(addr, w, 4)); } //------------------------------------------------------------------ // tc_r32 // // Read 32-bit word from given address. //------------------------------------------------------------------ static uint32_t tc_r32(const off_t addr) { uint8_t w[4]; check(tc_read(addr, w, 4)); return (uint32_t)((w[0] << 24) + (w[1] << 16) + (w[2] << 8) + w[3]); } //------------------------------------------------------------------ // check_modexp_access // // Check that we can read from the modexp core by trying to // read out the name and version. //------------------------------------------------------------------ static void check_modexp_access(void) { uint8_t name0[4], name1[4], version[4]; printf("Trying to read the modexp core name\n"); check(tc_read(MODEXP_ADDR_NAME0, name0, sizeof(name0))); check(tc_read(MODEXP_ADDR_NAME1, name1, sizeof(name1))); check(tc_read(MODEXP_ADDR_VERSION, version, sizeof(version))); printf("%4.4s%4.4s %4.4s\n\n", name0, name1, version); } //------------------------------------------------------------------ // check_modulus_mem() // // Check that we can write and read to the modulus memory. //------------------------------------------------------------------ static void check_modulus_mem(void) { uint8_t i; uint32_t j; printf("Testing modulus mem access.\n"); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); // Write test data to modulus mempory. for (i = 0 ; i < 64; i = i + 1) { j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) + ((i * 4 + 1) << 8) + i * 4; tc_w32(MODEXP_MODULUS_DATA, j); } tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); // Read out test data from modulus mempory. for (i = 0 ; i < 64 ; i = i + 4) { printf("modulus mem: 0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA)); } } //------------------------------------------------------------------ // check_exponent_mem() // // Check that we can write and read to the exponent memory. //------------------------------------------------------------------ static void check_exponent_mem(void) { uint8_t i; uint32_t j; printf("Testing exponent mem access.\n"); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); // Write test data to exponent memory. for (i = 0 ; i < 64; i = i + 1) { j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) + ((i * 4 + 1) << 8) + i * 4; tc_w32(MODEXP_EXPONENT_DATA, j); } tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); // Read out test data from exponent memory. for (i = 0 ; i < 64 ; i = i + 4) { printf("exponent mem: 0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA)); } } //------------------------------------------------------------------ // check_message_mem() // // Check that we can write and read to the message memory. //------------------------------------------------------------------ static void check_message_mem(void) { uint8_t i; uint32_t j; printf("Testing message mem access.\n"); tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); // Write test data to message memory. for (i = 0 ; i < 64; i = i + 1) { j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) + ((i * 4 + 1) << 8) + i * 4; tc_w32(MODEXP_MESSAGE_DATA, j); } tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); // Read out test data from messsage memory. for (i = 0 ; i < 64 ; i = i + 4) { printf("message mem: 0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA)); } } //------------------------------------------------------------------ // clear_mems() // // Zero fill the memories. //------------------------------------------------------------------ static void clear_mems() { uint32_t i; tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); for (i = 0 ; i < 256 ; i++) { tc_w32(MODEXP_MESSAGE_DATA, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x00000000); } tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); } //------------------------------------------------------------------ // dump_mems() // // Dump the first words from the memories. //------------------------------------------------------------------ static void dump_mems() { tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); printf("First words in messagee mem:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA)); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); printf("First words in exponent mem:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA)); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); printf("First words in modulus mem:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA)); tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); printf("First words in result mem:\n"); printf("0x%08x 0x%08x 0x%08x 0x%08x\n", tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA)); tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); } //------------------------------------------------------------------ // testrunner() //------------------------------------------------------------------ uint8_t testrunner(uint32_t exp_len, uint32_t *exponent, uint32_t mod_len, uint32_t *modulus, uint32_t *message, uint32_t *expected) { uint32_t i; uint32_t result; uint8_t correct; tc_w32(MODEXP_EXPONENT_LENGTH, exp_len); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); for (i = 0 ; i < mod_len ; i++) { tc_w32(MODEXP_EXPONENT_DATA, exponent[i]); } tc_w32(MODEXP_MODULUS_LENGTH, mod_len); tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); for (i = 0 ; i < mod_len ; i++) { tc_w32(MODEXP_MESSAGE_DATA, message[i]); tc_w32(MODEXP_MODULUS_DATA, modulus[i]); } tc_w32(MODEXP_ADDR_CTRL, 0x00000001); check(tc_wait_ready(MODEXP_ADDR_STATUS)); correct = 1; tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); for (i = 0 ; i < mod_len ; i++) { result = tc_r32(MODEXP_RESULT_DATA); if (result != expected[i]) { printf("TC1: Error. Expected 0x%08x, got 0x%08x\n", expected[i], result); correct = 0; } } return correct; } //------------------------------------------------------------------ // tc1() // // c = m ** e % N with the following (decimal) test values: // m = 3 // e = 7 // n = 11 (0x0b) // c = 3 ** 7 % 11 = 9 //------------------------------------------------------------------ static void tc1() { uint32_t exponent[1] = {0x00000007}; uint32_t modulus[1] = {0x0000000b}; uint32_t message[1] = {0x00000003}; uint32_t expected[1] = {0x00000009}; uint8_t result; printf("Running TC1: 0x03 ** 0x07 mod 0x0b = 0x09\n"); result = testrunner(1, &exponent[0], 1, &modulus[0], &message[0], &expected[0]); if (result) printf("TC1: OK\n"); else printf("TC1: NOT OK\n"); } //------------------------------------------------------------------ // tc2() // // c = m ** e % N with the following test values: // m = 251 (0xfb) // e = 251 (0xfb) // n = 257 (0x101) // c = 251 ** 251 % 257 = 183 (0xb7) //------------------------------------------------------------------ static void tc2() { uint32_t exponent[1] = {0x000000fb}; uint32_t modulus[1] = {0x00000101}; uint32_t message[1] = {0x000000fb}; uint32_t expected[1] = {0x000000b7}; uint8_t result; printf("Running TC2: 0xfb ** 0xfb mod 0x101 = 0xb7\n"); result = testrunner(1, &exponent[0], 1, &modulus[0], &message[0], &expected[0]); if (result) printf("TC2: OK\n"); else printf("TC2: NOT OK\n"); } //------------------------------------------------------------------ // tc3() // // c = m ** e % N with the following test values: // m = 0x81 // e = 0x41 // n = 0x87 // c = 0x81 ** 0x41 % 0x87 = 0x36 //------------------------------------------------------------------ static void tc3() { uint32_t exponent[1] = {0x00000041}; uint32_t modulus[1] = {0x00000087}; uint32_t message[1] = {0x00000081}; uint32_t expected[1] = {0x00000036}; uint8_t result; printf("Running TC3: 0x81 ** 0x41 mod 0x87 = 0x36\n"); result = testrunner(1, &exponent[0], 1, &modulus[0], &message[0], &expected[0]); if (result) printf("TC3: OK\n"); else printf("TC3: NOT OK\n"); } //------------------------------------------------------------------ // tc4() // // c = m ** e % N with the following test values: // m = 0x00000001946473e1 // e = 0xh000000010e85e74f // n = 0x0000000170754797 // c = 0x000000007761ed4f // // These operands spans two 32-bit words. //------------------------------------------------------------------ static void tc4() { uint32_t exponent[2] = {0x00000001, 0x0e85e74f}; uint32_t modulus[2] = {0x00000001, 0x70754797}; uint32_t message[2] = {0x00000001, 0x946473e1}; uint32_t expected[2] = {0x00000000, 0x7761ed4f}; uint8_t result; printf("Running TC4: 0x00000001946473e1 ** 0xh000000010e85e74f mod 0x0000000170754797 = 0x000000007761ed4f\n"); result = testrunner(2, &exponent[0], 2, &modulus[0], &message[0], &expected[0]); if (result) printf("TC4: OK\n"); else printf("TC4: NOT OK\n"); } //------------------------------------------------------------------ // tc5() // // c = m ** e % N with 128 bit operands. //------------------------------------------------------------------ static void tc5() { uint32_t exponent[4] = {0x3285c343, 0x2acbcb0f, 0x4d023228, 0x2ecc73db}; uint32_t modulus[4] = {0x267d2f2e, 0x51c216a7, 0xda752ead, 0x48d22d89}; uint32_t message[4] = {0x29462882, 0x12caa2d5, 0xb80e1c66, 0x1006807f}; uint32_t expected[4] = {0x0ddc404d, 0x91600596, 0x7425a8d8, 0xa066ca56}; uint8_t result; printf("Running TC5: 128 bit operands\n"); result = testrunner(4, &exponent[0], 4, &modulus[0], &message[0], &expected[0]); if (result) printf("TC5: OK\n"); else printf("TC5: NOT OK\n"); } //------------------------------------------------------------------ // main() //------------------------------------------------------------------ int main(void) { check_modexp_access(); // tc_set_debug(1); // check_modulus_mem(); // check_exponent_mem(); // check_message_mem(); tc1(); tc2(); tc3(); tc4(); tc5(); return 0; } //====================================================================== // EOF modexp_tester.c //======================================================================