//====================================================================== // // 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); } //------------------------------------------------------------------ // 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 result; printf("Running TC1: 0x03 ** 0x07 mod 0x0b = 0x09\n"); // Write operands and set associated lengths. tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MESSAGE_DATA, 0x00000003); tc_w32(MODEXP_LENGTH, 0x00000001); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x00000007); tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x0000000b); tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001); // Start processing and wait for ready. tc_w32(MODEXP_ADDR_CTRL, 0x00000001); check(tc_wait_ready(MODEXP_ADDR_STATUS)); // Check result with expected value. tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); result = tc_r32(MODEXP_RESULT_DATA); if (result == 0x00000009) printf("TC1: OK\n"); else printf("TC1: Error. Expected 0x00000009, got 0x%08x\n", result); } //------------------------------------------------------------------ // 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 result; printf("Running TC2: 0xfb ** 0xfb mod 0x101 = 0xb7\n"); // Write operands and set associated lengths. tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MESSAGE_DATA, 0x000000fb); tc_w32(MODEXP_MESSAGE_DATA, 0x00000000); tc_w32(MODEXP_LENGTH, 0x00000001); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x000000fb); tc_w32(MODEXP_EXPONENT_DATA, 0x00000000); tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x00000101); tc_w32(MODEXP_MODULUS_DATA, 0x00000000); tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001); // Start processing and wait for ready. printf("TC2: Starting processing. Waiting for ready...\n"); tc_w32(MODEXP_ADDR_CTRL, 0x00000001); check(tc_wait_ready(MODEXP_ADDR_STATUS)); printf("TC2: Ready seen.\n"); // Check result with expected value. tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); result = tc_r32(MODEXP_RESULT_DATA); if (result == 0x000000b7) printf("TC2: OK\n"); else printf("TC2: Error. Expected 0x000000b7, got 0x%08x\n", result); } //------------------------------------------------------------------ // 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 result; printf("Running TC3: 0x81 ** 0x41 mod 0x87 = 0x36\n"); // Write operands and set associated lengths. tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MESSAGE_DATA, 0x00000081); tc_w32(MODEXP_LENGTH, 0x00000001); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x00000041); tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x00000087); tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001); // Start processing and wait for ready. tc_w32(MODEXP_ADDR_CTRL, 0x00000001); check(tc_wait_ready(MODEXP_ADDR_STATUS)); // Check result with expected value. tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); result = tc_r32(MODEXP_RESULT_DATA); if (result == 0x00000036) printf("TC3: OK\n"); else printf("TC3: Error. Expected 0x00000036, got 0x%08x\n", result); } //------------------------------------------------------------------ // 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 result0, result1; uint32_t ready = 0; printf("Running TC4: 0x00000001946473e1 ** 0xh000000010e85e74f mod 0x0000000170754797 = 0x000000007761ed4f\n"); // Write operands and set associated lengths. tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MESSAGE_DATA, 0x00000001); tc_w32(MODEXP_MESSAGE_DATA, 0x946473e1); tc_w32(MODEXP_LENGTH, 0x00000002); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x00000001); tc_w32(MODEXP_EXPONENT_DATA, 0x0e85e74f); tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000002); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x00000001); tc_w32(MODEXP_MODULUS_DATA, 0x70754797); tc_w32(MODEXP_MODULUS_LENGTH, 0x00000002); // Start processing and wait for ready. tc_w32(MODEXP_ADDR_CTRL, 0x00000001); while (!ready) ready = tc_r32(MODEXP_ADDR_STATUS); // Check result with expected value. tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); result0 = tc_r32(MODEXP_RESULT_DATA); result1 = tc_r32(MODEXP_RESULT_DATA); if ((result0 == 0x00000000) && (result1 == 0x7761ed4f)) printf("TC4: OK\n"); else printf("TC4: Error. Expected 0x000000007761ed4f, got 0x%08x%08x\n", result0, result1); } //------------------------------------------------------------------ // tc5() // // c = m ** e % N with 128 bit operands. //------------------------------------------------------------------ static void tc5() { uint32_t result0, result1, result2, result3; printf("Running TC5: 128 bit operands.\n"); // Write operands and set associated lengths. tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000); tc_w32(MODEXP_MESSAGE_DATA, 0x29462882); tc_w32(MODEXP_MESSAGE_DATA, 0x12caa2d5); tc_w32(MODEXP_MESSAGE_DATA, 0xb80e1c66); tc_w32(MODEXP_MESSAGE_DATA, 0x1006807f); tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000); tc_w32(MODEXP_EXPONENT_DATA, 0x3285c343); tc_w32(MODEXP_EXPONENT_DATA, 0x2acbcb0f); tc_w32(MODEXP_EXPONENT_DATA, 0x4d023228); tc_w32(MODEXP_EXPONENT_DATA, 0x2ecc73db); tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000); tc_w32(MODEXP_MODULUS_DATA, 0x267d2f2e); tc_w32(MODEXP_MODULUS_DATA, 0x51c216a7); tc_w32(MODEXP_MODULUS_DATA, 0xda752ead); tc_w32(MODEXP_MODULUS_DATA, 0x48d22d89); tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000004); tc_w32(MODEXP_MODULUS_LENGTH, 0x00000004); // Start processing and wait for ready. tc_w32(MODEXP_ADDR_CTRL, 0x00000001); check(tc_wait_ready(MODEXP_ADDR_STATUS)); // Check result with expected value. tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000); result0 = tc_r32(MODEXP_RESULT_DATA); result1 = tc_r32(MODEXP_RESULT_DATA); result2 = tc_r32(MODEXP_RESULT_DATA); result3 = tc_r32(MODEXP_RESULT_DATA); if ((result0 == 0x0ddc404d) && (result1 == 0x91600596) && (result2 == 0x7425a8d8) && (result3 == 0xa066ca56)) printf("TC5: OK\n"); else printf("TC5: Error. Expected 0x0ddc404d 0x91600596 0x7425a8d8 0xa066ca56, got 0x%08x %08x0x %08x %08x\n", result0, result1, result2, result3); } //------------------------------------------------------------------ // main() //------------------------------------------------------------------ int main(void) { check_modexp_access(); // tc_set_debug(1); // check_modulus_mem(); // check_exponent_mem(); // check_message_mem(); tc1(); tc2(); tc3(); tc4(); return 0; } //====================================================================== // EOF modexp_tester.c //======================================================================