/* main-dsa-test.c */ /* This file is part of the ARM-Crypto-Lib. Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * RSA test-suit * */ #include "main-test-common.h" #include "noekeon.h" #include "noekeon_prng.h" #include "bigint.h" #include "bigint_io.h" #include "random_dummy.h" #include "rsa_basic.h" #include "rsassa_pkcs1v15.h" #include "sha1.h" #include "performance_test.h" const char* algo_name = "RSASA-PKCS15"; #define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)) #define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t)) /***************************************************************************** * additional validation-functions * *****************************************************************************/ /* Modulus: */ const uint8_t modulus[] = { 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb }; /* Public exponent: */ const uint8_t pub_exponent[] = { 0x01, 0x00, 0x01 }; /* Exponent: */ const uint8_t priv_exponent[] = { 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 }; /* Prime 1: */ const uint8_t p[] = { 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d }; /* Prime 2: */ const uint8_t q[] = { 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 }; /* Prime exponent 1: */ const uint8_t dp[] = { 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 }; /* Prime exponent 2: */ const uint8_t dq[] = { 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 }; /* Coefficient: */ const uint8_t qinv[] = { 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 }; /* * Example 2: A 1024-bit RSA key pair * --------------------------------------------------- */ /* Modulus: */ const uint8_t modulus2[] = { 0x98, 0xb7, 0x05, 0x82, 0xca, 0x80, 0x8f, 0xd1, 0xd3, 0x50, 0x95, 0x62, 0xa0, 0xef, 0x30, 0x5a, 0xf6, 0xd9, 0x87, 0x54, 0x43, 0xb3, 0x5b, 0xdf, 0x24, 0xd5, 0x36, 0x35, 0x3e, 0x3f, 0x12, 0x28, 0xdc, 0xd1, 0x2a, 0x78, 0x56, 0x83, 0x56, 0xc6, 0xff, 0x32, 0x3a, 0xbf, 0x72, 0xac, 0x1c, 0xdb, 0xfe, 0x71, 0x2f, 0xb4, 0x9f, 0xe5, 0x94, 0xa5, 0xa2, 0x17, 0x5d, 0x48, 0xb6, 0x73, 0x25, 0x38, 0xd8, 0xdf, 0x37, 0xcb, 0x97, 0x0b, 0xe4, 0xa5, 0xb5, 0x62, 0xc3, 0xf2, 0x98, 0xdb, 0x9d, 0xdf, 0x75, 0x60, 0x78, 0x77, 0x91, 0x8c, 0xce, 0xd1, 0xd0, 0xd1, 0xf3, 0x77, 0x33, 0x8c, 0x0d, 0x3d, 0x32, 0x07, 0x79, 0x7e, 0x86, 0x2c, 0x65, 0xd1, 0x14, 0x39, 0xe5, 0x88, 0x17, 0x75, 0x27, 0xa7, 0xde, 0xd9, 0x19, 0x71, 0xad, 0xcf, 0x91, 0xe2, 0xe8, 0x34, 0xe3, 0x7f, 0x05, 0xa7, 0x36, 0x55 }; /* Public exponent: */ const uint8_t pub_exponent2[] = {0x01, 0x00, 0x01 }; /* Exponent: */ const uint8_t priv_exponent2[] = { 0x06, 0x14, 0xa7, 0x86, 0x05, 0x2d, 0x28, 0x4c, 0xd9, 0x06, 0xa8, 0xe4, 0x13, 0xf7, 0x62, 0x2c, 0x05, 0x0f, 0x35, 0x49, 0xc0, 0x26, 0x58, 0x9e, 0xa2, 0x77, 0x50, 0xe0, 0xbe, 0xd9, 0x41, 0x0e, 0x5a, 0x78, 0x83, 0xa1, 0xe6, 0x03, 0xf5, 0xc5, 0x17, 0xad, 0x36, 0xd4, 0x9f, 0xaa, 0xc5, 0xbd, 0x66, 0xbc, 0xb8, 0x03, 0x0f, 0xa8, 0xd3, 0x09, 0xe3, 0x51, 0xdd, 0xd7, 0x82, 0xd8, 0x43, 0xdf, 0x97, 0x56, 0x80, 0xae, 0x73, 0xee, 0xa9, 0xaa, 0xb2, 0x89, 0xb7, 0x57, 0x20, 0x5d, 0xad, 0xb8, 0xfd, 0xfb, 0x98, 0x9e, 0xc8, 0xdb, 0x8e, 0x70, 0x95, 0xf5, 0x1f, 0x24, 0x52, 0x9f, 0x56, 0x37, 0xaa, 0x66, 0x93, 0x31, 0xe2, 0x56, 0x9f, 0x8b, 0x85, 0x4a, 0xbe, 0xce, 0xc9, 0x9a, 0xa2, 0x64, 0xc3, 0xda, 0x7c, 0xc6, 0x86, 0x6f, 0x0c, 0x0e, 0x1f, 0xb8, 0x46, 0x98, 0x48, 0x58, 0x1c, 0x73 }; /* Prime 1: */ const uint8_t p2[] = { 0xcb, 0x61, 0xa8, 0x8c, 0x8c, 0x30, 0x5a, 0xd9, 0xa8, 0xfb, 0xec, 0x2b, 0xa4, 0xc8, 0x6c, 0xcc, 0xc2, 0x02, 0x80, 0x24, 0xaa, 0x16, 0x90, 0xc2, 0x9b, 0xc8, 0x26, 0x4d, 0x2f, 0xeb, 0xe8, 0x7e, 0x4f, 0x86, 0xe9, 0x12, 0xef, 0x0f, 0x5c, 0x18, 0x53, 0xd7, 0x1c, 0xbc, 0x9b, 0x14, 0xba, 0xed, 0x3c, 0x37, 0xce, 0xf6, 0xc7, 0xa3, 0x59, 0x8b, 0x6f, 0xbe, 0x06, 0x48, 0x10, 0x90, 0x5b, 0x57 }; /* Prime 2: */ const uint8_t q2[] = { 0xc0, 0x39, 0x9f, 0x0b, 0x93, 0x80, 0xfa, 0xba, 0x38, 0xff, 0x80, 0xd2, 0xff, 0xf6, 0xed, 0xe7, 0x9c, 0xfd, 0xab, 0xf6, 0x58, 0x97, 0x20, 0x77, 0xa5, 0xe2, 0xb2, 0x95, 0x69, 0x3e, 0xa5, 0x10, 0x72, 0x26, 0x8b, 0x91, 0x74, 0x6e, 0xea, 0x9b, 0xe0, 0x4a, 0xd6, 0x61, 0x00, 0xeb, 0xed, 0x73, 0x3d, 0xb4, 0xcd, 0x01, 0x47, 0xa1, 0x8d, 0x6d, 0xe8, 0xc0, 0xcd, 0x8f, 0xbf, 0x24, 0x9c, 0x33 }; /* Prime exponent 1: */ const uint8_t dp2[] = { 0x94, 0x4c, 0x3a, 0x65, 0x79, 0x57, 0x4c, 0xf7, 0x87, 0x33, 0x62, 0xab, 0x14, 0x35, 0x9c, 0xb7, 0xd5, 0x03, 0x93, 0xc2, 0xa8, 0x4f, 0x59, 0xf0, 0xbd, 0x3c, 0xbd, 0x48, 0xed, 0x17, 0x7c, 0x68, 0x95, 0xbe, 0x8e, 0xb6, 0xe2, 0x9f, 0xf5, 0x8c, 0x3b, 0x9e, 0x0f, 0xf3, 0x2a, 0xb5, 0x7b, 0xf3, 0xbe, 0x44, 0x07, 0x62, 0x84, 0x81, 0x84, 0xaa, 0x9a, 0xa9, 0x19, 0xd5, 0x74, 0x56, 0x7e, 0x73 }; /* Prime exponent 2: */ const uint8_t dq2[] = { 0x45, 0xeb, 0xef, 0xd5, 0x87, 0x27, 0x30, 0x8c, 0xd2, 0xb4, 0xe6, 0x08, 0x5a, 0x81, 0x58, 0xd2, 0x9a, 0x41, 0x8f, 0xee, 0xc1, 0x14, 0xe0, 0x03, 0x85, 0xbc, 0xeb, 0x96, 0xfb, 0xbc, 0x84, 0xd0, 0x71, 0xa5, 0x61, 0xb9, 0x5c, 0x30, 0x08, 0x79, 0x00, 0xe2, 0x58, 0x0e, 0xdb, 0x05, 0xf6, 0xce, 0xa7, 0x90, 0x7f, 0xcd, 0xca, 0x5f, 0x92, 0x91, 0x7b, 0x4b, 0xbe, 0xba, 0x5e, 0x1e, 0x14, 0x0f }; /* Coefficient: */ const uint8_t qinv2[] = { 0xc5, 0x24, 0x68, 0xc8, 0xfd, 0x15, 0xe5, 0xda, 0x2f, 0x6c, 0x8e, 0xba, 0x4e, 0x97, 0xba, 0xeb, 0xe9, 0x95, 0xb6, 0x7a, 0x1a, 0x7a, 0xd7, 0x19, 0xdd, 0x9f, 0xff, 0x36, 0x6b, 0x18, 0x4d, 0x5a, 0xb4, 0x55, 0x07, 0x59, 0x09, 0x29, 0x20, 0x44, 0xec, 0xb3, 0x45, 0xcf, 0x2c, 0xdd, 0x26, 0x22, 0x8e, 0x21, 0xf8, 0x51, 0x83, 0x25, 0x5f, 0x4a, 0x9e, 0x69, 0xf4, 0xc7, 0x15, 0x2e, 0xbb, 0x0f }; /* PKCS#1 v1.5 signatures * --------------------------------------------------------------------------- */ /* Message to be signed */ const uint8_t message_1_1[] = { 0xcd, 0xc8, 0x7d, 0xa2, 0x23, 0xd7, 0x86, 0xdf, 0x3b, 0x45, 0xe0, 0xbb, 0xbc, 0x72, 0x13, 0x26, 0xd1, 0xee, 0x2a, 0xf8, 0x06, 0xcc, 0x31, 0x54, 0x75, 0xcc, 0x6f, 0x0d, 0x9c, 0x66, 0xe1, 0xb6, 0x23, 0x71, 0xd4, 0x5c, 0xe2, 0x39, 0x2e, 0x1a, 0xc9, 0x28, 0x44, 0xc3, 0x10, 0x10, 0x2f, 0x15, 0x6a, 0x0d, 0x8d, 0x52, 0xc1, 0xf4, 0xc4, 0x0b, 0xa3, 0xaa, 0x65, 0x09, 0x57, 0x86, 0xcb, 0x76, 0x97, 0x57, 0xa6, 0x56, 0x3b, 0xa9, 0x58, 0xfe, 0xd0, 0xbc, 0xc9, 0x84, 0xe8, 0xb5, 0x17, 0xa3, 0xd5, 0xf5, 0x15, 0xb2, 0x3b, 0x8a, 0x41, 0xe7, 0x4a, 0xa8, 0x67, 0x69, 0x3f, 0x90, 0xdf, 0xb0, 0x61, 0xa6, 0xe8, 0x6d, 0xfa, 0xae, 0xe6, 0x44, 0x72, 0xc0, 0x0e, 0x5f, 0x20, 0x94, 0x57, 0x29, 0xcb, 0xeb, 0xe7, 0x7f, 0x06, 0xce, 0x78, 0xe0, 0x8f, 0x40, 0x98, 0xfb, 0xa4, 0x1f, 0x9d, 0x61, 0x93, 0xc0, 0x31, 0x7e, 0x8b, 0x60, 0xd4, 0xb6, 0x08, 0x4a, 0xcb, 0x42, 0xd2, 0x9e, 0x38, 0x08, 0xa3, 0xbc, 0x37, 0x2d, 0x85, 0xe3, 0x31, 0x17, 0x0f, 0xcb, 0xf7, 0xcc, 0x72, 0xd0, 0xb7, 0x1c, 0x29, 0x66, 0x48, 0xb3, 0xa4, 0xd1, 0x0f, 0x41, 0x62, 0x95, 0xd0, 0x80, 0x7a, 0xa6, 0x25, 0xca, 0xb2, 0x74, 0x4f, 0xd9, 0xea, 0x8f, 0xd2, 0x23, 0xc4, 0x25, 0x37, 0x02, 0x98, 0x28, 0xbd, 0x16, 0xbe, 0x02, 0x54, 0x6f, 0x13, 0x0f, 0xd2, 0xe3, 0x3b, 0x93, 0x6d, 0x26, 0x76, 0xe0, 0x8a, 0xed, 0x1b, 0x73, 0x31, 0x8b, 0x75, 0x0a, 0x01, 0x67, 0xd0 }; /* Signature: */ const uint8_t sign_1_1[] = { 0x6b, 0xc3, 0xa0, 0x66, 0x56, 0x84, 0x29, 0x30, 0xa2, 0x47, 0xe3, 0x0d, 0x58, 0x64, 0xb4, 0xd8, 0x19, 0x23, 0x6b, 0xa7, 0xc6, 0x89, 0x65, 0x86, 0x2a, 0xd7, 0xdb, 0xc4, 0xe2, 0x4a, 0xf2, 0x8e, 0x86, 0xbb, 0x53, 0x1f, 0x03, 0x35, 0x8b, 0xe5, 0xfb, 0x74, 0x77, 0x7c, 0x60, 0x86, 0xf8, 0x50, 0xca, 0xef, 0x89, 0x3f, 0x0d, 0x6f, 0xcc, 0x2d, 0x0c, 0x91, 0xec, 0x01, 0x36, 0x93, 0xb4, 0xea, 0x00, 0xb8, 0x0c, 0xd4, 0x9a, 0xac, 0x4e, 0xcb, 0x5f, 0x89, 0x11, 0xaf, 0xe5, 0x39, 0xad, 0xa4, 0xa8, 0xf3, 0x82, 0x3d, 0x1d, 0x13, 0xe4, 0x72, 0xd1, 0x49, 0x05, 0x47, 0xc6, 0x59, 0xc7, 0x61, 0x7f, 0x3d, 0x24, 0x08, 0x7d, 0xdb, 0x6f, 0x2b, 0x72, 0x09, 0x61, 0x67, 0xfc, 0x09, 0x7c, 0xab, 0x18, 0xe9, 0xa4, 0x58, 0xfc, 0xb6, 0x34, 0xcd, 0xce, 0x8e, 0xe3, 0x58, 0x94, 0xc4, 0x84, 0xd7 }; uint8_t keys_allocated = 0; rsa_publickey_t pub_key; rsa_privatekey_t priv_key; #if 1 #define MSG message_1_1 #define SIGN sign_1_1 #define MODULUS modulus2 #define PUB_EXPONENT pub_exponent2 #define PRIV_EXPONENT priv_exponent2 #define P p2 #define Q q2 #define DP dp2 #define DQ dq2 #define QINV qinv2 #endif uint8_t convert_nibble(uint8_t c){ if(c>='0' && c<='9'){ return c - '0'; } c |= 'A' ^ 'a'; if(c>='a' && c<='f'){ return c - 'a' + 10; } return 0xff; } const char *block_ignore_string=" \t\r\n,;"; #define BUFFER_LIMIT 120 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){ uint16_t counter = 0; uint16_t c; uint8_t v, tmp = 0, idx = 0; if(!ignore_string){ ignore_string = block_ignore_string; } while(counter < length){ c = cli_getc(); if(c > 0xff){ return counter; } if(strchr(ignore_string, c)){ continue; } v = convert_nibble(c); if(v > 0x0f){ return counter; } if(idx){ ((uint8_t*)dst)[counter++] = (tmp << 4) | v; idx = 0; if(counter % (BUFFER_LIMIT/2) == 0){ cli_putc('.'); } }else{ tmp = v; idx = 1; } } return counter; } uint16_t own_atou(const char* str){ uint16_t r=0; while(*str && *str >= '0' && *str <= '9'){ r *= 10; r += *str++ - '0'; } return r; } uint8_t read_bigint(bigint_t* a, char* prompt){ uint16_t read_length, actual_length; uint8_t off; uint8_t *buffer; char read_int_str[18]; cli_putstr(prompt); cli_putstr("\r\n length: "); cli_getsn(read_int_str, 16); read_length = own_atou(read_int_str); off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t); buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)); if(!buffer){ cli_putstr("\r\nERROR: OOM!"); return 2; } cli_putstr("\r\n data: "); memset(buffer, 0, sizeof(bigint_word_t)); actual_length = read_os(buffer + off, read_length, NULL); if(actual_length != read_length){ cli_putstr("\r\nERROR: unexpected end of data!"); free(buffer); return 1; } a->wordv = (bigint_word_t*)buffer; a->length_W = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); a->info = 0; bigint_changeendianess(a); bigint_adjust(a); return 0; } uint8_t pre_alloc_key_crt(void){ priv_key.n = 5; priv_key.components = malloc(5 * sizeof(bigint_t)); if(!priv_key.components){ cli_putstr("\r\nERROR: OOM!"); return 2; } return 0; } void free_key(void){ uint8_t c; free(pub_key.modulus.wordv); free(pub_key.exponent.wordv); pub_key.modulus.wordv = priv_key.modulus.wordv = NULL; for(c = 0; c < priv_key.n; ++c){ free(priv_key.components[c].wordv); } free(priv_key.components); } uint8_t read_key_crt(void){ uint8_t r; cli_putstr("\r\n== reading key (crt) =="); r = pre_alloc_key_crt(); if(r) return r; r = read_bigint(&pub_key.modulus, "\r\n = module ="); memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t)); if(r) return r; r = read_bigint(&pub_key.exponent, "\r\n = public exponent ="); if(r) return r; r = read_bigint(&priv_key.components[0], "\r\n = p (first prime) ="); if(r) return r; r = read_bigint(&priv_key.components[1], "\r\n = q (second prime) ="); if(r) return r; r = read_bigint(&priv_key.components[2], "\r\n = dp (p's exponent) ="); if(r) return r; r = read_bigint(&priv_key.components[3], "\r\n = dq (q's exponent) ="); if(r) return r; r = read_bigint(&priv_key.components[4], "\r\n = qInv (q' coefficient) ="); return r; } uint8_t read_key_conv(void){ uint8_t r; cli_putstr("\r\n== reading key (crt) =="); r = read_bigint(&pub_key.modulus,"\r\n = module ="); if(r) return r; memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t)); priv_key.n = 1; priv_key.components = malloc(sizeof(bigint_t)); if(!priv_key.components){ cli_putstr("\r\nERROR: OOM!"); return 2; } r = read_bigint(&pub_key.exponent, "\r\n = public exponent ="); if(r) return r; r = read_bigint(&priv_key.components[0], "\r\n = private exponent ="); return r; } void load_priv_conventional(void){ priv_key.components = malloc(sizeof(bigint_t)); priv_key.components[0].length_W = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); priv_key.components[0].wordv = malloc(priv_key.components[0].length_W * sizeof(bigint_word_t)); if(!priv_key.components[0].wordv){ cli_putstr("\r\nERROR: OOM!"); return; } memcpy(priv_key.components[0].wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT)); priv_key.n = 1; bigint_changeendianess(&priv_key.components[0]); bigint_adjust(&priv_key.components[0]); } void load_priv_crt_mono(void){ bigint_t *v; const uint8_t *bv[5] = {P,Q,DP,DQ,QINV}; uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)}; uint8_t i; v = malloc(5 * sizeof(bigint_t)); if(!v){ cli_putstr("\r\nERROR: OOM!"); return; } priv_key.components = v; priv_key.n = 5; for(i=0; i<5; ++i){ v[i].info = 0; v[i].length_W = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); v[i].wordv = calloc(v[i].length_W , sizeof(bigint_word_t)); if(!v[i].wordv){ cli_putstr("\r\nERROR: OOM!"); return; } memcpy(v[i].wordv, bv[i], sv[i]); bigint_changeendianess(&v[i]); bigint_adjust(&v[i]); } } uint8_t load_bigint_from_os(bigint_t* a, const void* os, uint16_t length_B){ a->length_W = BIGINT_CEIL(length_B) / sizeof(bigint_word_t); a->wordv = malloc(BIGINT_CEIL(length_B)); if(!a->wordv){ cli_putstr("\r\nOOM!\r\n"); return 1; } memset(a->wordv, 0, sizeof(bigint_word_t)); memcpy((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B); a->info = 0; bigint_changeendianess(a); bigint_adjust(a); return 0; } void load_fix_rsa(void){ if(keys_allocated){ free_key(); } keys_allocated = 1; if(pre_alloc_key_crt()){ cli_putstr("\r\nOOM!\r\n"); return; } load_bigint_from_os(&pub_key.modulus, MODULUS, sizeof(MODULUS)); load_bigint_from_os(&pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT)); priv_key.n = 5; memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t)); load_bigint_from_os(&priv_key.components[0], P, sizeof(P)); load_bigint_from_os(&priv_key.components[1], Q, sizeof(Q)); load_bigint_from_os(&priv_key.components[2], DP, sizeof(DP)); load_bigint_from_os(&priv_key.components[3], DQ, sizeof(DQ)); load_bigint_from_os(&priv_key.components[4], QINV, sizeof(QINV)); // load_priv_conventional(); // load_priv_crt_mono(); } void quick_test(void){ uint8_t *msg, *sign, hash[20], rc; uint16_t slen; if(!keys_allocated){ load_fix_rsa(); } msg = malloc(sizeof(MSG)); memcpy(msg, MSG, sizeof(MSG)); sign = malloc(pub_key.modulus.length_W * sizeof(bigint_word_t)); cli_putstr("\r\nhashing:..."); sha1(hash, msg, sizeof(MSG) * 8); cli_putstr("\r\nsigning: ..."); rc = rsa_sign_pkcs1v15(sign, &slen, hash, 20, &priv_key, &pkcs1v15_sha1_prefix); if(rc){ cli_putstr("\r\nERROR: rsa_sign_pkcs1v15() returned: "); cli_hexdump_byte(rc); return; } cli_putstr("\r\n\r\nsignature:"); cli_hexdump_block(sign, slen, 4, 16); if(slen!=sizeof(SIGN)){ cli_putstr("\r\n>>FAIL (no size match)<<"); }else{ if(memcmp(sign, SIGN, slen)){ cli_putstr("\r\n>>FAIL (no content match)<<"); }else{ cli_putstr("\r\n>>OK<<"); } } cli_putstr("\r\nverifying: ..."); rc = rsa_verify_pkcs1v15(sign, slen, hash, 20, &pub_key, &pkcs1v15_sha1_prefix); if(rc){ cli_putstr("\r\nERROR: rsa_verify_pkcs1v15() returned: "); cli_hexdump_byte(rc); return; }else{ cli_putstr("\r\nsignature >>OK<<"); } free(sign); free(msg); } void run_sha1_test(void){ uint8_t *msg, *sign, hash[20], rc; uint16_t msg_len, sign_len; char read_int_str[18]; cli_putstr("\r\n== test with given seed =="); cli_putstr("\r\n = message ="); cli_putstr("\r\n length: "); cli_getsn(read_int_str, 16); msg_len = own_atou(read_int_str); msg = malloc(msg_len); if(!msg){ cli_putstr("\r\nERROR: OOM!"); return; } sign = malloc(bigint_length_B(&pub_key.modulus)); if(!sign){ cli_putstr("\r\nERROR: OOM!"); return; } cli_putstr("\r\n data: "); read_os(msg, msg_len, NULL); cli_putstr("\r\n hashing ..."); sha1(hash, msg, msg_len * 8); cli_putstr("\r\n signing ..."); /* cli_putstr("\r\n plaintext:"); cli_hexdump_block(msg, msg_len, 4, 16); cli_putstr("\r\n seed:"); cli_hexdump_block(seed, seed_len, 4, 16); */ rc = rsa_sign_pkcs1v15(sign, &sign_len, hash, 20, &priv_key, &pkcs1v15_sha1_prefix); if(rc){ cli_putstr("\r\n ERROR: computing signature failed with code: "); cli_hexdump_byte(rc); } cli_putstr("\r\n signature:"); cli_hexdump_block(sign, sign_len, 4, 16); cli_putstr("\r\n verifying ... "); rc = rsa_verify_pkcs1v15(sign, sign_len, hash, 20, &pub_key, &pkcs1v15_sha1_prefix); cli_putstr("[done]"); if(rc){ cli_putstr("\r\n ERROR: verifying signature failed with code: "); cli_hexdump_byte(rc); }else{ cli_putstr("\r\n >>OK<<"); } free(sign); free(msg); } void reset_prng(void){ uint8_t buf[16]; memset(buf, 0, 16); random_seed(buf); cli_putstr("\r\nPRNG reset"); } void rsa_init(void){ prng_get_byte = random8; } void load_key(void){ if(keys_allocated){ free_key(); } keys_allocated = 1; read_key_crt(); } void test_dump(void){ char lstr[16]; int len; cli_putstr("\r\nenter dump length: "); cli_getsn(lstr, 15); len = own_atou(lstr); cli_putstr("\r\ndumping 0x"); cli_hexdump_rev(&len, 2); cli_putstr(" byte:"); cli_hexdump_block(pub_key.modulus.wordv, len, 4, 8); } /***************************************************************************** * main * *****************************************************************************/ const char echo_test_str[] = "echo-test"; const char reset_prng_str[] = "reset-prng"; const char load_key_str[] = "load-key"; const char load_fix_key_str[] = "load-fix-key"; const char quick_test_str[] = "quick-test"; const char sha1_test_str[] = "sha1-test"; const char dump_test_str[] = "dump-test"; const char performance_str[] = "performance"; const char echo_str[] = "echo"; const cmdlist_entry_t cmdlist[] = { { reset_prng_str, NULL, reset_prng }, { load_key_str, NULL, load_key }, { load_fix_key_str, NULL, load_fix_rsa }, { quick_test_str, NULL, quick_test }, { sha1_test_str, NULL, run_sha1_test }, { dump_test_str, NULL, test_dump }, // { performance_str, NULL, testrun_performance_bigint }, { echo_str, (void*)1, (void_fpt)echo_ctrl }, { NULL, NULL, NULL } }; void dump_sp(void){ uint8_t x; uint8_t *xa = &x; cli_putstr("\r\nstack pointer: ~"); cli_hexdump_rev(&xa, 4); } int main (void){ main_setup(); for(;;){ welcome_msg(algo_name); rsa_init(); cmd_interface(cmdlist); } }