/** * @file algorithmTest.c * @version $Format:%h%d$ * * Crypto harness to check algorithms against known inputs/outputs. */ /* * Copyright (c) 2013-2018 Rambus Inc. * Copyright (c) PeerSec Networks, 2002-2011 * All Rights Reserved * * The latest version of this code is available at http://www.matrixssl.org * * This software is open source; 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 2 of the License, or * (at your option) any later version. * * This General Public License does NOT permit incorporating this software * into proprietary programs. If you are unable to comply with the GPL, a * commercial license for this software may be purchased from Rambus at * http://www.rambus.com/ * * This program is distributed in 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * http://www.gnu.org/copyleft/gpl.html */ /******************************************************************************/ #include "crypto/cryptoImpl.h" #include "psUtil.h" #include "hmac_test_vectors.h" #include "osdep_stdio.h" #include "osdep_string.h" #include "crypto/digest/sha256_standalone.h" #ifndef USE_SERVER_SIDE_SSL # define USE_SERVER_SIDE_SSL #endif /* Allow FAIL_IF() just like in cl's tests. */ #define INTSTR2(x) #x #define INTSTR(x) INTSTR2(x) #define FAIL_IF(x) \ do \ { \ if (x) \ { \ _psTraceStr(" FAILED (condition=%s)\n", \ #x" [line="INTSTR(__LINE__)"]"); \ return -1; \ } \ } while(0) /******************************************************************************/ static int32 psPrngTests(void) { int32 res; static unsigned char ch[70000]; _psTrace(" PRNG small random generation... "); Memset(ch, 0, sizeof(ch)); res = psGetPrngLocked(ch, 3, NULL); if (res != 3 || ch[0] + ch[1] + ch[2] < 6 || /* Probabilistic test */ ch[4] != 0 || ch[5] != 0) { _psTrace("FAILED\n"); res = PS_FAILURE; } else { _psTrace("PASSED\n"); } if (res != PS_FAILURE) { int i, sum; _psTrace(" PRNG large random generation... "); Memset(ch, 0, sizeof(ch)); sum = 0; res = psGetPrngLocked(ch + 1, 65532, NULL); res += psGetPrngLocked(ch + 1 + 65532, (69998 - 65532), NULL); for (i = 0; i < 70000; i++) { sum += ch[i]; } if (res != 69998 || sum < 5 * 70000 || /* Probabilistic test */ sum > 250 * 70000 || /* Probabilistic test */ ch[0] != 0 || ch[69999] != 0) { _psTrace("FAILED\n"); res = PS_FAILURE; } else { _psTrace("PASSED\n"); } } return res < 0 ? res : PS_SUCCESS; } #ifdef USE_HKDF static int32 psHkdfTests(void) { int32_t rc; unsigned char res[1024] = {0}; psSize_t resLen; #ifdef USE_HMAC_SHA256 /* Test case 1 */ _psTrace("\tTest case 1 from RFC 5869... "); unsigned char ikm1[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; unsigned char salt1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; unsigned char info1[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; unsigned char prk1[] = { 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5 }; unsigned char okm1[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 }; rc = psHkdfExtract(HMAC_SHA256, salt1, sizeof(salt1), ikm1, sizeof(ikm1), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk1)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk1, sizeof(prk1))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA256, prk1, sizeof(prk1), info1, sizeof(info1), res, sizeof(okm1)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm1, sizeof(okm1))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); /* Test case 2 */ _psTrace("\tTest case 2 from RFC 5869... "); unsigned char ikm2[] = { 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, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; unsigned char salt2[] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf }; unsigned char info2[] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; unsigned char prk2[] = { 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01, 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44 }; unsigned char okm2[] = { 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87, }; rc = psHkdfExtract(HMAC_SHA256, salt2, sizeof(salt2), ikm2, sizeof(ikm2), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk2)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk2, sizeof(prk2))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA256, prk2, sizeof(prk2), info2, sizeof(info2), res, sizeof(okm2)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm2, sizeof(okm2))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); /* Test case 3 */ _psTrace("\tTest case 3 from RFC 5869... "); unsigned char ikm3[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, }; unsigned char salt3[] = {}; unsigned char info3[] = {}; unsigned char prk3[] = { 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77, 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04 }; unsigned char okm3[] = { 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8 }; rc = psHkdfExtract(HMAC_SHA256, salt3, sizeof(salt3), ikm3, sizeof(ikm3), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk3)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk3, sizeof(prk3))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA256, prk3, sizeof(prk3), info3, sizeof(info3), res, sizeof(okm3)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm3, sizeof(okm3))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); #endif // USE_HMAC_SHA256 #ifdef USE_HMAC_SHA1 /* Test case 4 */ _psTrace("\tTest case 4 from RFC 5869... "); unsigned char ikm4[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; unsigned char salt4[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; unsigned char info4[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; unsigned char prk4[] = { 0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f, 0x0e, 0x71, 0xc8, 0xeb, 0x88, 0xf4, 0xb3, 0x0b, 0xaa, 0x2b, 0xa2, 0x43 }; unsigned char okm4[] = { 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15, 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96 }; rc = psHkdfExtract(HMAC_SHA1, salt4, sizeof(salt4), ikm4, sizeof(ikm4), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk4)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk4, sizeof(prk4))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA1, prk4, sizeof(prk4), info4, sizeof(info4), res, sizeof(okm4)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm4, sizeof(okm4))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); /* Test case 5 */ _psTrace("\tTest case 5 from RFC 5869... "); unsigned char ikm5[] = { 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, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; unsigned char salt5[] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf }; unsigned char info5[] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; unsigned char prk5[] = { 0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59, 0x47, 0x8d, 0x30, 0x9b, 0x26, 0xc4, 0x11, 0x5a, 0x22, 0x4c, 0xfa, 0xf6 }; unsigned char okm5[] = { 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19, 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c, 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43, 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4, }; rc = psHkdfExtract(HMAC_SHA1, salt5, sizeof(salt5), ikm5, sizeof(ikm5), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk5)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk5, sizeof(prk5))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA1, prk5, sizeof(prk5), info5, sizeof(info5), res, sizeof(okm5)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm5, sizeof(okm5))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); /* Test case 6 */ _psTrace("\tTest case 6 from RFC 5869... "); unsigned char ikm6[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, }; unsigned char salt6[] = {}; unsigned char info6[] = {}; unsigned char prk6[] = { 0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28, 0x8e, 0xc6, 0xf5, 0xe7, 0xc2, 0x97, 0x78, 0x6a, 0xa0, 0xd3, 0x2d, 0x01, }; unsigned char okm6[] = { 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06, 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18, }; rc = psHkdfExtract(HMAC_SHA1, salt6, sizeof(salt6), ikm6, sizeof(ikm6), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk6)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk6, sizeof(prk6))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA1, prk6, sizeof(prk6), info6, sizeof(info6), res, sizeof(okm6)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm6, sizeof(okm6))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); /* Test case 7 */ _psTrace("\tTest case 7 from RFC 5869... "); unsigned char ikm7[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }; unsigned char info7[] = {}; unsigned char prk7[] = { 0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c, 0x20, 0x77, 0xad, 0x2e, 0xb1, 0x9d, 0x3f, 0x3e, 0x73, 0x13, 0x85, 0xdd }; unsigned char okm7[] = { 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23, 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48 }; rc = psHkdfExtract(HMAC_SHA1, NULL, 0, ikm7, sizeof(ikm7), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk7)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk7, sizeof(prk7))) { _psTrace("FAILED\n"); return PS_FAILURE; } rc = psHkdfExpand(HMAC_SHA1, prk7, sizeof(prk7), info7, sizeof(info7), res, sizeof(okm7)); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, okm7, sizeof(okm7))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); #endif // USE_HMAC_SHA1 #ifdef USE_HMAC_384 /* Test case 8 */ _psTrace("\tSHA384 HKDF-Extract (RFC4231 case 3)... "); unsigned char ikm8[] = { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }; unsigned char salt8[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; unsigned char prk8[] = { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f, 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb, 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b, 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9, 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 }; rc = psHkdfExtract(HMAC_SHA384, salt8, sizeof(salt8), ikm8, sizeof(ikm8), res, &resLen); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (resLen != sizeof(prk8)) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, prk8, sizeof(prk8))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); #endif // USE_HMAC_384 return PS_SUCCESS; } static int32 psHkdfExpandLabelTests(void) { #ifdef USE_HMAC_SHA256 _psTrace("\t's hs traffic' test... "); /* This test vector is under the heading "{server} derive secret "tls13 s hs traffic":" on page 4 of draft-ietf-tls-tls13-vectors-03. Renamed the inputs for clarity. PRK --> secret hash --> transcript_hash info --> This is not actually used in the test. This the HkdfLabel that psHkdfExpandLabel should construct from the following input: (secret, label == "s hs traffic", context == hash)). output --> expect */ unsigned char secret1[] = { 0x79, 0x07, 0xc2, 0x82, 0x34, 0xf1, 0x6c, 0xa8, 0x71, 0xa4, 0x6b, 0xeb, 0x25, 0xda, 0x54, 0x7f, 0xdc, 0x8a, 0xab, 0x96, 0xd1, 0x4e, 0xef, 0xf8, 0x0f, 0x5b, 0x12, 0xf9, 0xad, 0x8a, 0xc9, 0xd6 }; unsigned char transcript_hash1[] = { 0x2a, 0x63, 0xe9, 0x0b, 0x84, 0xe5, 0xc9, 0x79, 0x80, 0x56, 0x98, 0x41, 0x19, 0x3b, 0x80, 0x94, 0x22, 0x19, 0x36, 0x52, 0x19, 0xad, 0x23, 0x90, 0xb6, 0x80, 0x64, 0xc2, 0xae, 0xbb, 0x09, 0x69 }; const char *label1 = "s hs traffic"; unsigned char expect1[] = { 0xa2, 0xc1, 0x53, 0x5b, 0x55, 0x26, 0x42, 0x8b, 0x49, 0xcb, 0xe6, 0xcc, 0x3c, 0x19, 0x23, 0x7c, 0x37, 0x4e, 0x94, 0xdb, 0x25, 0x6c, 0x96, 0x4d, 0x4d, 0x13, 0x76, 0xa9, 0xde, 0x1a, 0xc5, 0x12 }; unsigned char res[sizeof(expect1)] = {0}; int32_t rc; rc = psHkdfExpandLabel(NULL, HMAC_SHA256, secret1, sizeof(secret1), label1, strlen(label1), transcript_hash1, sizeof(transcript_hash1), sizeof(expect1), res); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, expect1, sizeof(expect1))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); psTrace("\t'finished' test... "); unsigned char secret2[] = { 0xa2, 0xc1, 0x53, 0x5b, 0x55, 0x26, 0x42, 0x8b, 0x49, 0xcb, 0xe6, 0xcc, 0x3c, 0x19, 0x23, 0x7c, 0x37, 0x4e, 0x94, 0xdb, 0x25, 0x6c, 0x96, 0x4d, 0x4d, 0x13, 0x76, 0xa9, 0xde, 0x1a, 0xc5, 0x12, }; unsigned char transcript_hash2[] = {}; const char *label2 = "finished"; unsigned char expect2[] = { 0xd2, 0x7d, 0x01, 0xab, 0xe2, 0xd9, 0xd6, 0x68, 0x98, 0xdc, 0x10, 0xf8, 0x5d, 0x92, 0x2f, 0xd6, 0xff, 0xf5, 0x1d, 0xb8, 0x80, 0xf4, 0xaf, 0x64, 0x52, 0xb7, 0x1c, 0x05, 0xc3, 0xfc, 0x42, 0x67 }; rc = psHkdfExpandLabel(NULL, HMAC_SHA256, secret2, sizeof(secret2), label2, strlen(label2), transcript_hash2, sizeof(transcript_hash2), sizeof(expect2), res); if (rc < 0) { _psTrace("FAILED\n"); return PS_FAILURE; } if (Memcmp(res, expect2, sizeof(expect2))) { _psTrace("FAILED\n"); return PS_FAILURE; } _psTrace("PASSED\n"); #endif return PS_SUCCESS; } #endif /******************************************************************************/ #ifdef USE_AES # define AES_ITER 1000 /* For AES Block mode test */ static int32 psAesTestBlock(void) { int32 err, i, y; psAesKey_t ekey, dkey; unsigned char tmp[2][16]; static const struct { int32 keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } }, { 24, { 0x00,0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, { 0x00,0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0xdd,0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } }, { 32, { 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 }, { 0x00,0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0x8e,0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } } }; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" AES-%d known vector test... ", tests[i].keylen * 8); if ((err = psAesInitBlockKey(&ekey, tests[i].key, tests[i].keylen, PS_AES_ENCRYPT)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesInitBlockKey returned %d\n", err); return err; } if ((err = psAesInitBlockKey(&dkey, tests[i].key, tests[i].keylen, PS_AES_DECRYPT)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesInitBlockKey returned %d\n", err); psAesClearBlockKey(&ekey); return err; } psAesEncryptBlock(&ekey, tests[i].pt, tmp[0]); psAesDecryptBlock(&dkey, tmp[0], tmp[1]); if (Memcmp(tmp[0], tests[i].ct, 16) || Memcmp(tmp[1], tests[i].pt, 16)) { _psTraceInt("FAILED: mem compare failed\n", i); if (Memcmp(tmp[0], tests[i].ct, 16)) { psTraceCrypto("CT: "); for (i = 0; i < 16; i++) { _psTraceInt("%02x ", tmp[0][i]); } _psTrace("\n"); } else { _psTrace("PT: "); for (i = 0; i < 16; i++) { _psTraceInt("%02x ", tmp[1][i]); } _psTrace("\n"); } psAesClearBlockKey(&ekey); psAesClearBlockKey(&dkey); return -1; } _psTrace("PASSED\n"); /* Now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ _psTraceInt(" AES-%d wind/unwind test... ", tests[i].keylen * 8); for (y = 0; y < 16; y++) { tmp[0][y] = 0; } for (y = 0; y < AES_ITER; y++) { psAesEncryptBlock(&ekey, tmp[0], tmp[0]); } for (y = 0; y < AES_ITER; y++) { psAesDecryptBlock(&dkey, tmp[0], tmp[0]); } for (y = 0; y < 16; y++) { if (tmp[0][y] != 0) { _psTraceInt("FAILED: unable to unwind %d to zero\n", y); psAesClearBlockKey(&ekey); psAesClearBlockKey(&dkey); return -1; } } psAesClearBlockKey(&ekey); psAesClearBlockKey(&dkey); _psTrace("PASSED\n"); } return 0; } # ifdef USE_AES_CBC /* Known vector test - AES-CBC */ static int32 psAesTestCBC(void) { int32 err, i; psAesCbc_t eCtx, dCtx; unsigned char tmp[2][16]; static struct { int32 keylen; unsigned char key[32], iv[16], pt[16], ct[16]; } tests[] = { { 16, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d } }, { 24, { 0x8e,0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, { 0x00,0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x6b,0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x4f,0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8 } }, { 32, { 0x60,0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73,0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, { 0x00,0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x6b,0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0xf5,0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6 } } }; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" AES-CBC-%d known vector test... ", tests[i].keylen * 8); if ((err = psAesInitCBC(&eCtx, tests[i].iv, tests[i].key, tests[i].keylen, PS_AES_ENCRYPT)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesInitCBC returned %d\n", err); return err; } if ((err = psAesInitCBC(&dCtx, tests[i].iv, tests[i].key, tests[i].keylen, PS_AES_DECRYPT)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesInitCBC returned %d\n", err); psAesClearCBC(&eCtx); return err; } psAesEncryptCBC(&eCtx, tests[i].pt, tmp[0], 16); psAesDecryptCBC(&dCtx, tmp[0], tmp[1], 16); if (Memcmp(tmp[0], tests[i].ct, 16) || Memcmp(tmp[1], tests[i].pt, 16)) { _psTraceInt("FAILED: mem compare failed\n", i); if (Memcmp(tmp[0], tests[i].ct, 16)) { psTraceCrypto("CT: "); for (i = 0; i < 16; i++) { _psTraceInt("%02x ", tmp[0][i]); } _psTrace("\n"); } else { _psTrace("PT: "); for (i = 0; i < 16; i++) { _psTraceInt("%02x ", tmp[1][i]); } _psTrace("\n"); } psAesClearCBC(&eCtx); psAesClearCBC(&dCtx); return -1; } psAesClearCBC(&eCtx); psAesClearCBC(&dCtx); _psTrace("PASSED\n"); } return 0; } # endif /* USE_AES_CBC */ # ifdef USE_AES_GCM int32 psAesTestGCM2(void) { int32 res = PS_SUCCESS; int32_t rc; psAesGcm_t ctx; unsigned char nonce[12] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12 }; unsigned char decrypted[256] = { 0 }; unsigned char tdata[] = { 't', 'e', 's', 't', 'd', 'a', 't', 'a', 't', 'e', 's', 't', 'd', 'a', 't', 'a', 't', 'e', 's', 't', 'd', 'a', 't', 'a', 't', 'e', 's', 't', 'd', 'a', 't', 'a' }; unsigned char ct[64] = { 0 }; unsigned char key[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; unsigned char aad[5] = { 0x17, 0x03, 0x03, 0xff, 0xff }; unsigned char kat_pt[256]; unsigned char kat_ct[256]; const unsigned char kat_key[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }; const unsigned char kat_nonce[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; const unsigned char kat_adata[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; const unsigned char kat_expect_ct[] = { 0x82, 0xcb, 0x7c, 0xad, 0x6a, 0x6e, 0x31, 0x65, 0xbd, 0xe9, 0xca, 0x33, 0xd3, 0x53, 0x1a, 0x1c, 0xf0, 0x31, 0x16, 0x2d, 0xed, 0x88, 0xad, 0x66, 0x32, 0x99, 0x24, 0xff, 0xaa, 0x3d, 0x1a, 0x8d, 0x75, 0x23, 0x3a, 0x56, 0x6b, 0x24, 0xef, 0x9a, 0x9c, 0x53, 0x67, 0xed, 0x2e, 0x52, 0xcb, 0x0d, 0xe8, 0x19, 0xc4, 0x38, 0xee, 0xab, 0xfd, 0xd8, 0x5f, 0x09, 0xd6, 0x19, 0x8c, 0xf0, 0xd4, 0xd0, 0x35, 0xdf, 0x77, 0x81, 0x75, 0xe4, 0x77, 0xd1, 0x49, 0xa6, 0xea, 0x09, 0x03, 0x16, 0xf6, 0x77, 0x93, 0xe7, 0x64, 0xbc, 0x98, 0x8c, 0xd4, 0x44, 0xd2, 0x0f, 0x73, 0x16, 0x6c, 0x17, 0x7c, 0x54, 0xd9, 0xaf, 0x3b, 0x91, 0xda, 0x64, 0x7f, 0x63, 0x18, 0x04, 0xa7, 0x86, 0xf1, 0x84, 0x0f, 0xf4, 0xe9, 0xa1, 0xdb, 0xa5, 0x7f, 0x41, 0xf5, 0x6d, 0xa0, 0x8b, 0x65, 0x22, 0x1f, 0x35, 0x49, 0x55, 0xe1, 0x83, 0x83, 0x31, 0xf0, 0x69, 0x15, 0xb3, 0xd1, 0x15, 0x13, 0x01, 0x6b, 0x75, 0xf1, 0x7b, 0x0a, 0x66, 0x15, 0xd7, 0xfc, 0x8d, 0x45, 0x11, 0xf2, 0x16, 0x37, 0xc4, 0x92, 0x00, 0xa9, 0x6e, 0x79, 0xc0, 0xcb, 0xed, 0x50, 0x37, 0xfb, 0xb7, 0xcb, 0xeb, 0x2d, 0x06, 0xbe, 0xbc, 0x56, 0x09, 0xba, 0xd1, 0xca, 0xec, 0x96, 0x4b, 0xda, 0xa2, 0x18, 0xf7, 0x93, 0xca, 0xa8, 0x38, 0x09, 0x86, 0xbf, 0x24, 0xae, 0xe2, 0x4f, 0x9c, 0x9b, 0x8d, 0xf4, 0x43, 0xe1, 0xd6, 0x87, 0x99, 0x7e, 0x0a, 0xad, 0xa3, 0xe2, 0x08, 0x89, 0x9f, 0x9e, 0xd1, 0xf9, 0xb5, 0x47, 0x63, 0x0e, 0x39, 0xab, 0x09, 0x96, 0xfe, 0x2a, 0x5c, 0x70, 0xbd, 0xd9, 0x85, 0xe9, 0x3a, 0x10, 0x2c, 0xe8, 0x82, 0x8b, 0x8c, 0x7a, 0xff, 0x69, 0xad, 0xbd, 0xb3, 0x25, 0x76, 0x1d, 0x0c, 0x21, 0xd1, 0xa8, 0xf7, 0x12, 0x28 }; const unsigned char kat_expect_tag[] = { 0xab, 0xfe, 0x16, 0xcf, 0x17, 0xae, 0x2c, 0xd3, 0x15, 0x72, 0x9f, 0x1c, 0x9d, 0xb2, 0xff, 0x6d }; int i; Printf(" AES-GCM pairwise test with AAD... "); psAesInitGCM(&ctx, key, sizeof(key)); psAesReadyGCM(&ctx, nonce, aad, sizeof(aad)); psAesEncryptGCMImplicitIV(&ctx, tdata, ct, sizeof(tdata)); psAesGetGCMTag(&ctx, 16, ct + sizeof(tdata)); psAesClearGCM(&ctx); psAesInitGCM(&ctx, key, sizeof(key)); psAesReadyGCM(&ctx, nonce, aad, sizeof(aad)); rc = psAesDecryptGCM(&ctx, ct, sizeof(tdata) + 16, decrypted, sizeof(tdata)); if (rc < 0) { Printf("FAILED: psAesDecryptGCM failed\n"); res = PS_FAILURE; abort(); goto out; } if (Memcmp(tdata, decrypted, sizeof(tdata))) { Printf("GCM enc/dec pairwise test failed\n"); res = PS_FAILURE; abort(); goto out; } psAesClearGCM(&ctx); Printf("PASSED\n"); Printf(" AES-GCM pairwise test with no AAD... "); psAesInitGCM(&ctx, key, sizeof(key)); psAesReadyGCM(&ctx, nonce, NULL, 0); psAesEncryptGCMImplicitIV(&ctx, tdata, ct, sizeof(tdata)); psAesGetGCMTag(&ctx, 16, ct + sizeof(tdata)); psAesClearGCM(&ctx); psAesInitGCM(&ctx, key, sizeof(key)); psAesReadyGCM(&ctx, nonce, NULL, 0); rc = psAesDecryptGCM(&ctx, ct, sizeof(tdata) + 16, decrypted, sizeof(tdata)); if (rc < 0) { Printf("FAILED: psAesDecryptGCM failed\n"); res = PS_FAILURE; abort(); goto out; } if (Memcmp(tdata, decrypted, sizeof(tdata))) { Printf("GCM enc/dec pairwise test failed\n"); res = PS_FAILURE; abort(); goto out; } psAesClearGCM(&ctx); Printf("PASSED\n"); Printf(" AES-GCM KAT with AAD... "); for(i = 0; i < 256; i++) { kat_pt[i] = 0xff ^ i; } psAesInitGCM(&ctx, kat_key, sizeof(kat_key)); psAesReadyGCM(&ctx, kat_nonce, kat_adata, sizeof(kat_adata)); psAesEncryptGCMImplicitIV(&ctx, kat_pt, kat_ct, sizeof(kat_ct)); if (Memcmp(kat_ct, kat_expect_ct, sizeof(kat_expect_ct))) { Printf("GCM KAT failed\n"); res = PS_FAILURE; abort(); goto out; } psAesGetGCMTag(&ctx, 16, kat_ct + 16); if (Memcmp(kat_ct + 16, kat_expect_tag, sizeof(kat_expect_tag))) { Printf("GCM KAT failed\n"); res = PS_FAILURE; abort(); goto out; } Printf("PASSED\n"); out: psAesClearGCM(&ctx); return res; } int32 psAesTestGCM(void) { int32 res = PS_SUCCESS; int32 i, l; psAesGcm_t eCtx; psAesGcm_t dCtx; unsigned char plaintext[4128]; unsigned char ciphertext[4128]; unsigned char ciphertext_rand[4128]; unsigned char plaintext_rand[4128]; unsigned char tag[16]; unsigned char ciphertext_with_tag[4144]; unsigned char iv[12]; static unsigned char taglen[3] = { 8, 12, 16 }; static char *tagmsg[] = { " AES-GCM-%d known vector decrypt (taglen=8) test... ", " AES-GCM-%d known vector decrypt (taglen=12) test... ", " AES-GCM-%d known vector decrypt (taglen=16) test... ", }; static char *tagmsg2[] = { " AES-GCM-%d known vector decrypt (taglen=8 invalid) test... ", " AES-GCM-%d known vector decrypt (taglen=12 invalid) test... ", " AES-GCM-%d known vector decrypt (taglen=16 invalid) test... ", }; static struct { int32 keylen, ptlen, aadlen; unsigned char key[32], iv[12], pt[4128], aad[32], ct[4128], tag[16]; } tests[] = { # ifndef USE_LIBSODIUM_AES_GCM { 16, 16, 16, { 0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37, 0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c }, { 0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3, 0x9e, 0x0f, 0x67, 0xe2 }, { 0xc3, 0xb3, 0xc4, 0x1f, 0x11, 0x3a, 0x31, 0xb7, 0x3d, 0x9a, 0x5c, 0xd4, 0x32, 0x10, 0x30, 0x69 }, { 0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84, 0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f }, { 0x93, 0xfe, 0x7d, 0x9e, 0x9b, 0xfd, 0x10, 0x34, 0x8a, 0x56, 0x06, 0xe5, 0xca, 0xfa, 0x73, 0x54 }, { 0x00, 0x32, 0xa1, 0xdc, 0x85, 0xf1, 0xc9, 0x78, 0x69, 0x25, 0xa2, 0xe7, 0x1d, 0x82, 0x72, 0xdd } }, { 16, 4128, 16, { 0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37, 0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c }, { 0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3, 0x9e, 0x0f, 0x67, 0xe2 }, { 0x00, }, { 0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84, 0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f }, { 0x50, 0x4d, 0xb9, 0x81, 0x8a, 0xc7, 0x21, 0x83,0xb7, 0xcc, 0x5a, 0x31, 0xf8, 0xea, 0x43, 0x3d, 0x46, 0xb1, 0x85, 0x3f, 0x8b, 0x9b, 0x8d, 0xd3, 0xfe, 0x06, 0x84, 0x42, 0xd9, 0x08, 0x98, 0x43, 0xe7, 0xbd, 0x0b, 0x32, 0x02, 0x10, 0x39, 0xae, 0x3b, 0xcb, 0x39, 0x5d, 0x76, 0x47, 0xd8, 0xc9, 0xac, 0xa1, 0x72, 0xe7, 0x54, 0x98, 0xcf, 0x5f, 0x91, 0x56, 0x90, 0x51, 0x79, 0x3a, 0xf3, 0x38, 0x4e, 0xb2, 0x8d, 0x1a, 0x27, 0x3c, 0xa9, 0xdb, 0x8f, 0xcd, 0x48, 0x14, 0x97, 0xba, 0xd7, 0x4b, 0x7c, 0x64, 0xc4, 0x78, 0xf7, 0x8f, 0x81, 0x22, 0x71, 0xa6, 0x90, 0xf4, 0x30, 0x47, 0xd8, 0x7f, 0x96, 0xd9, 0x6c, 0x21, 0xc0, 0x47, 0xfd, 0xc8, 0x45, 0xf8, 0x7d, 0xdf, 0x8c, 0x2b, 0x1a, 0xe5, 0x73, 0x29, 0x7f, 0x26, 0x55, 0xb4, 0x11, 0x4a, 0x08, 0x2d, 0x30, 0xab, 0x12, 0x58, 0x96, 0xf8, 0xfa, 0x99, 0x75, 0x6a, 0x0c, 0x94, 0x5c, 0x71, 0x58, 0x3f, 0x9c, 0xca, 0x96, 0x8e, 0xfd, 0x90, 0x88, 0xf6, 0x3a, 0x23, 0xdb, 0xf0, 0xca, 0x5a, 0x4a, 0x8e, 0x29, 0x42, 0xdb, 0xa8, 0x87, 0x74, 0xd4, 0xae, 0x9a, 0x6d, 0xf5, 0x6e, 0x00, 0xda, 0x0a, 0x03, 0x17, 0xa3, 0x3a, 0xa5, 0xd1, 0x13, 0x9e, 0x81, 0xf2, 0xc8, 0xf7, 0x07, 0xfa, 0xe8, 0x83, 0x1a, 0x00, 0x56, 0xd2, 0xf2, 0x80, 0x6a, 0xe4, 0xf1, 0x4e, 0xda, 0x56, 0x66, 0xeb, 0xaf, 0xad, 0x0c, 0x19, 0xe8, 0x30, 0xb3, 0x8b, 0x59, 0x9c, 0xbf, 0x10, 0x38, 0xa7, 0xaf, 0x2a, 0xd3, 0x52, 0xae, 0xb0, 0x6e, 0x3a, 0x01, 0x3f, 0xc9, 0x13, 0xdb, 0x99, 0xe5, 0xb5, 0x59, 0x2b, 0x14, 0x48, 0xf3, 0xb5, 0x93, 0x38, 0xa8, 0x12, 0x98, 0x6c, 0x83, 0x88, 0x32, 0x7a, 0x46, 0x46, 0xae, 0xed, 0x81, 0x1c, 0xba, 0xab, 0xb3, 0x2e, 0xa0, 0x53, 0x57, 0x8c, 0x24, 0x80, 0x7b, 0x9d, 0x74, 0xb9, 0xf5, 0x52, 0x01, 0x4f, 0x4c, 0x51, 0x21, 0x1c, 0x4b, 0x6a, 0xe3, 0x00, 0x3e, 0x4c, 0xcb, 0x40, 0xf8, 0xf4, 0x31, 0x8a, 0xa0, 0xbf, 0xf0, 0x4c, 0x02, 0x7d, 0x47, 0x2d, 0x37, 0xe8, 0x6b, 0x20, 0xec, 0xef, 0xf1, 0xb0, 0xaf, 0x87, 0x31, 0x06, 0x76, 0x1b, 0x59, 0x9a, 0x92, 0xfa, 0x94, 0x7a, 0x76, 0xf5, 0x6f, 0x16, 0xde, 0x96, 0xb6, 0x0e, 0xe0, 0x59, 0x09, 0x1e, 0x0f, 0xf7, 0x27, 0x59, 0xf5, 0xe4, 0x01, 0x57, 0x88, 0x6c, 0x32, 0x73, 0x68, 0xbb, 0x63, 0xe0, 0x3b, 0x57, 0xbd, 0xc5, 0x40, 0xbf, 0x5d, 0x8a, 0xd6, 0x3c, 0x13, 0x40, 0x89, 0x74, 0x87, 0x82, 0xdb, 0x13, 0x90, 0x0f, 0x42, 0x91, 0x8c, 0x35, 0xdf, 0x1f, 0x2a, 0xb1, 0x36, 0x73, 0x49, 0x26, 0x40, 0x35, 0x5e, 0x60, 0xa8, 0x58, 0x23, 0xe6, 0x14, 0x9d, 0x51, 0x61, 0x7c, 0x6f, 0x82, 0x88, 0x4f, 0x96, 0xba, 0xe2, 0x7a, 0x14, 0x65, 0x26, 0xdb, 0xf5, 0xc2, 0x8a, 0x07, 0xbc, 0x42, 0x2d, 0x33, 0x0f, 0x94, 0xfa, 0xdd, 0x1a, 0xe7, 0x54, 0xda, 0x08, 0x1d, 0xdf, 0xb6, 0x03, 0x5c, 0x51, 0x7e, 0xcf, 0xf8, 0x8f, 0x21, 0xd1, 0xad, 0x29, 0x6c, 0x29, 0xee, 0x5a, 0x90, 0xf2, 0x0f, 0xd5, 0xe5, 0x29, 0x2e, 0x98, 0x2e, 0x36, 0x0e, 0x97, 0x42, 0x73, 0x9c, 0xc1, 0x54, 0x02, 0x2f, 0xde, 0xb1, 0x86, 0x3b, 0x69, 0x77, 0xe2, 0xc5, 0xa8, 0x71, 0xc8, 0x11, 0x6e, 0x64, 0x33, 0x87, 0xa2, 0x17, 0xfc, 0x84, 0x5e, 0x20, 0x0b, 0xc9, 0x25, 0x0c, 0xcb, 0x7f, 0xe2, 0xfe, 0x18, 0x02, 0x59, 0x4a, 0x58, 0x41, 0xe1, 0x47, 0xcc, 0xdf, 0x00, 0x51, 0x6d, 0x78, 0xa5, 0x81, 0x8b, 0x7b, 0x24, 0x32, 0x7d, 0x39, 0x9a, 0xed, 0x4c, 0xc3, 0x7a, 0x8d, 0x64, 0xe9, 0x6f, 0xdb, 0x24, 0x25, 0xa7, 0x99, 0x44, 0xca, 0x99, 0x46, 0xa1, 0x48, 0x3b, 0x78, 0x31, 0xf8, 0x7d, 0x49, 0x02, 0x4f, 0x07, 0x7d, 0x13, 0x9e, 0x16, 0x03, 0x3a, 0xec, 0x32, 0x44, 0x6a, 0x8d, 0x9b, 0xbd, 0xf0, 0xf3, 0x01, 0xf2, 0xa6, 0x3d, 0x84, 0x54, 0xb5, 0x8b, 0xe3, 0x84, 0xe3, 0xa5, 0x15, 0xe3, 0x18, 0xef, 0x76, 0xd1, 0xd0, 0x02, 0x10, 0xfd, 0x47, 0xdf, 0xe6, 0x32, 0x8f, 0xca, 0xa9, 0x0d, 0xa0, 0xa7, 0x55, 0xaa, 0x4a, 0xee, 0x99, 0x8c, 0x8f, 0x52, 0x0e, 0xd3, 0x24, 0xc7, 0x4f, 0x50, 0xc9, 0x4e, 0x69, 0xc8, 0x53, 0xc7, 0xb1, 0x5f, 0x2e, 0x4f, 0xb3, 0xc5, 0x08, 0xfa, 0x9a, 0x29, 0x30, 0x5e, 0x9c, 0x38, 0xcf, 0x83, 0xb9, 0xbf, 0x38, 0x4c, 0x23, 0xe2, 0xc4, 0x1e, 0x7f, 0x96, 0x6c, 0xfc, 0x82, 0x50, 0xb1, 0x9e, 0xbc, 0xe8, 0xcf, 0xa7, 0x3c, 0x16, 0x5f, 0x6f, 0x8e, 0xda, 0xbc, 0x30, 0xc5, 0xbf, 0x78, 0xeb, 0xa8, 0xe7, 0x4f, 0xd3, 0x12, 0x6a, 0xb2, 0xa3, 0xc1, 0x0b, 0x15, 0x3a, 0xe0, 0x1d, 0x3e, 0x4e, 0xdd, 0x19, 0x6b, 0xfc, 0xca, 0x5c, 0xdd, 0x48, 0xbf, 0xf1, 0x37, 0x02, 0x2d, 0x3c, 0xeb, 0xda, 0x01, 0xb1, 0x60, 0x0c, 0x08, 0x99, 0xb5, 0x41, 0x10, 0x52, 0x2b, 0x90, 0x50, 0xac, 0xe3, 0x48, 0x5a, 0xac, 0x6f, 0x5e, 0x00, 0x2d, 0xeb, 0x78, 0x17, 0x36, 0xf8, 0x8f, 0x11, 0x9e, 0x28, 0xe7, 0x58, 0x4f, 0x82, 0xcb, 0xce, 0x02, 0x57, 0x4e, 0xee, 0xcc, 0xe9, 0x87, 0x69, 0x39, 0xe3, 0x2c, 0x2c, 0xdf, 0xe4, 0xcd, 0xfc, 0x4e, 0xaf, 0xa8, 0xe5, 0x95, 0x20, 0x58, 0x4f, 0x3c, 0x61, 0xe7, 0xba, 0xf3, 0xbe, 0x2a, 0x34, 0xd8, 0x40, 0x16, 0xd3, 0xf7, 0x2d, 0xd6, 0x3f, 0x9a, 0x4e, 0x34, 0x6b, 0x82, 0x6d, 0x47, 0x99, 0x14, 0x42, 0x9c, 0xc9, 0xea, 0x3c, 0xfe, 0xaa, 0x12, 0x1f, 0xe2, 0x7f, 0xbd, 0x0d, 0x50, 0x99, 0x9b, 0x49, 0x64, 0x04, 0x77, 0x86, 0x6d, 0xaa, 0xbd, 0xa7, 0x83, 0xe7, 0x9d, 0x1a, 0xdd, 0x52, 0x1c, 0x5e, 0xbb, 0x75, 0x04, 0x96, 0xca, 0xdc, 0xaa, 0x49, 0xe0, 0x66, 0x74, 0x30, 0x8b, 0xe9, 0x35, 0x5d, 0xfc, 0x92, 0x9c, 0x0b, 0x38, 0xcb, 0xbd, 0xff, 0x93, 0xe5, 0xc1, 0xeb, 0xcf, 0x87, 0x2a, 0x17, 0x3e, 0xda, 0xc5, 0xa1, 0x12, 0xe5, 0x81, 0xd5, 0x20, 0x31, 0x29, 0xe9, 0xd3, 0x31, 0x92, 0x1b, 0x20, 0x5a, 0x1d, 0x65, 0xd3, 0xa8, 0x25, 0x68, 0xe8, 0xa2, 0x39, 0xc3, 0xfa, 0xde, 0x6f, 0xfc, 0x04, 0x8b, 0x23, 0xa8, 0xf9, 0xd1, 0xee, 0x54, 0x83, 0x82, 0xc6, 0x48, 0xa2, 0x59, 0x74, 0x80, 0xcf, 0xb7, 0x9f, 0x4a, 0x01, 0x1e, 0xe5, 0x03, 0x30, 0x43, 0xb3, 0x0c, 0x05, 0x14, 0x87, 0x7a, 0x04, 0x06, 0x8b, 0x5f, 0x92, 0x36, 0x4b, 0x0b, 0xe9, 0x2c, 0x00, 0x08, 0x6f, 0xb9, 0x77, 0xc3, 0x9c, 0x0e, 0xb8, 0x43, 0x01, 0x8f, 0xe9, 0x53, 0x8c, 0x46, 0xdf, 0x94, 0x63, 0x87, 0x94, 0xee, 0xe2, 0xed, 0xab, 0xf5, 0xf0, 0x70, 0xac, 0xad, 0x06, 0x53, 0x59, 0x8b, 0x0c, 0x67, 0x47, 0xee, 0xb4, 0x26, 0x95, 0xe9, 0x46, 0x89, 0xe6, 0x1c, 0xa2, 0x08, 0xe9, 0xc5, 0x06, 0xe1, 0x16, 0x39, 0xfd, 0xb2, 0x46, 0xa3, 0x7e, 0x91, 0xc7, 0x56, 0x49, 0xda, 0xaa, 0x32, 0x7a, 0xe9, 0x80, 0x3d, 0x8c, 0xe9, 0x41, 0x75, 0xe9, 0xc6, 0x1f, 0xbb, 0xf7, 0x6e, 0xe9, 0x13, 0x74, 0x7b, 0x3f, 0xd1, 0x68, 0xd1, 0xa1, 0x7a, 0x66, 0x66, 0x07, 0x0e, 0xa4, 0x0e, 0xd3, 0xff, 0x9b, 0x75, 0x75, 0x34, 0xbe, 0xa8, 0x1c, 0xb1, 0xc4, 0x00, 0x6e, 0x6e, 0x32, 0x2d, 0x49, 0xfe, 0xa0, 0x14, 0xc6, 0x55, 0x4c, 0x36, 0x40, 0x79, 0x16, 0xd0, 0xd5, 0x17, 0xb0, 0xfa, 0xf8, 0xe2, 0xed, 0xac, 0x12, 0x7d, 0x1e, 0x27, 0xba, 0x89, 0x5a, 0xde, 0x9a, 0xeb, 0xf1, 0x2e, 0x3f, 0x3f, 0x7f, 0xf7, 0x99, 0x70, 0xd7, 0x2d, 0xf2, 0xe2, 0xee, 0x05, 0xd1, 0xd2, 0xd9, 0x7f, 0x70, 0xdc, 0x19, 0xc4, 0x6f, 0x7a, 0x5c, 0xb0, 0x45, 0x17, 0x17, 0x57, 0x92, 0xf6, 0xab, 0xbe, 0x28, 0x19, 0x48, 0x8f, 0x97, 0x76, 0xdf, 0xc4, 0x44, 0x0a, 0x1b, 0xe7, 0xa5, 0xb2, 0x70, 0x92, 0x64, 0x15, 0x99, 0x09, 0xbb, 0xbb, 0xe9, 0x02, 0x56, 0x54, 0xb0, 0xe8, 0x49, 0xf6, 0x98, 0xcd, 0x58, 0x7a, 0xb2, 0x5f, 0xc4, 0x9d, 0x54, 0xa4, 0x75, 0xfd, 0x49, 0x60, 0xf1, 0x8d, 0xbf, 0x2c, 0x23, 0x13, 0xa6, 0xb9, 0x6c, 0x87, 0x5a, 0x2d, 0xb8, 0x42, 0xa6, 0x84, 0x99, 0x55, 0x33, 0x2e, 0x15, 0x5e, 0xd4, 0xc9, 0xf3, 0xd3, 0xb9, 0xe8, 0x71, 0xf6, 0xc6, 0x49, 0xac, 0x6d, 0x0c, 0x63, 0xec, 0xf0, 0xf9, 0x48, 0x78, 0x45, 0xba, 0x50, 0xac, 0xa8, 0xfe, 0x94, 0x3c, 0x53, 0x18, 0x8b, 0x2e, 0xc6, 0x9d, 0x6c, 0x09, 0x13, 0xf1, 0x19, 0x4d, 0xcd, 0x0e, 0xb0, 0x75, 0xc0, 0x48, 0x19, 0xaa, 0xb1, 0x13, 0x5f, 0xb8, 0x7f, 0xe9, 0x8d, 0xe8, 0x1f, 0xd2, 0x6a, 0xf4, 0x80, 0x42, 0xd4, 0x9c, 0x34, 0x10, 0xc2, 0xc4, 0xe2, 0x08, 0x1a, 0x6d, 0xbc, 0x2e, 0x2a, 0x82, 0x36, 0x32, 0x95, 0x0d, 0x25, 0xaf, 0xed, 0xca, 0x17, 0xb2, 0x42, 0x86, 0x76, 0x76, 0x40, 0x88, 0x56, 0x5d, 0xe3, 0x41, 0x62, 0x8f, 0xc3, 0x64, 0xac, 0xe7, 0x8e, 0x39, 0x0a, 0xe1, 0xc1, 0x9d, 0x4b, 0x01, 0x9c, 0xe9, 0xda, 0x67, 0xef, 0x7f, 0x6c, 0xd3, 0xa0, 0x27, 0xc1, 0xab, 0xbe, 0xa6, 0xa5, 0x19, 0x27, 0x5a, 0x55, 0x35, 0x70, 0xe7, 0xf5, 0xa0, 0xfa, 0x0a, 0xce, 0x93, 0xea, 0xd4, 0xbf, 0xbd, 0x08, 0x20, 0x01, 0x76, 0x1d, 0x65, 0x1e, 0x1d, 0x6e, 0x28, 0x0e, 0x1c, 0x22, 0x43, 0xf3, 0x25, 0x77, 0x7c, 0xe4, 0x3b, 0x3a, 0x1f, 0x04, 0x77, 0x19, 0x88, 0x57, 0xf1, 0x89, 0x14, 0xba, 0x05, 0xf0, 0x38, 0x87, 0x48, 0xb3, 0x62, 0x5d, 0x8d, 0x79, 0xe7, 0x7f, 0x07, 0x7c, 0x7f, 0xaf, 0x31, 0x86, 0x51, 0x8d, 0x89, 0x2d, 0x50, 0x6f, 0xab, 0xf6, 0x41, 0xb1, 0xc9, 0x24, 0x6b, 0x32, 0xf4, 0xe0, 0x89, 0xec, 0x4e, 0xbe, 0x9b, 0x15, 0xf4, 0xa4, 0xd3, 0x0b, 0x49, 0x8c, 0xd4, 0x9a, 0x81, 0xa8, 0x03, 0x79, 0x2d, 0xfe, 0xa7, 0x6d, 0x32, 0x22, 0x43, 0xcc, 0xa5, 0xeb, 0x8b, 0xf5, 0x20, 0xc7, 0x73, 0x2d, 0xa0, 0xc8, 0x88, 0x27, 0xe3, 0x1f, 0xa6, 0x03, 0x3a, 0x8f, 0xf6, 0x31, 0xda, 0x31, 0x09, 0x5e, 0xd6, 0xe0, 0x7f, 0xc4, 0xa9, 0xa4, 0x58, 0x50, 0xfe, 0xb9, 0x15, 0x78, 0xc6, 0xb3, 0x52, 0xeb, 0xe1, 0x09, 0x21, 0x2d, 0xaf, 0x09, 0xf8, 0xea, 0xfa, 0xb2, 0x85, 0x55, 0x8e, 0x2d, 0xc3, 0xc3, 0x3b, 0xd7, 0xa8, 0x97, 0x9d, 0x16, 0x78, 0x50, 0x52, 0x86, 0x3a, 0xf3, 0xc6, 0xbe, 0xe6, 0xbd, 0xdb, 0xa4, 0x9a, 0x24, 0x80, 0xb0, 0xc9, 0x70, 0x91, 0x29, 0xe4, 0x52, 0xf5, 0xb5, 0x08, 0x7b, 0x54, 0x01, 0xd8, 0x0e, 0x61, 0xe6, 0x6b, 0xf8, 0x55, 0xcf, 0x26, 0x53, 0xa4, 0x61, 0x5b, 0xeb, 0x3d, 0x73, 0x88, 0x7e, 0x59, 0x3d, 0x8b, 0x23, 0xae, 0x6c, 0x4b, 0xf5, 0x93, 0x5e, 0xc6, 0xf6, 0x2d, 0x37, 0x9f, 0x62, 0x25, 0xf6, 0xcc, 0x85, 0x3c, 0x16, 0xc3, 0x94, 0x66, 0xd8, 0xd8, 0x52, 0x6d, 0xa8, 0x69, 0x1e, 0x28, 0xa6, 0xe1, 0x7d, 0xc7, 0x86, 0xa1, 0xe4, 0x5d, 0x01, 0xeb, 0xb9, 0x09, 0xd8, 0xec, 0x2a, 0x6e, 0x21, 0xc9, 0x29, 0x1f, 0xc8, 0x85, 0xc0, 0x7f, 0x43, 0xb6, 0x32, 0x3a, 0x69, 0xaf, 0xc5, 0x0b, 0xa5, 0x86, 0xd8, 0x1b, 0xa3, 0x2a, 0xeb, 0x12, 0x31, 0xdd, 0xe7, 0x54, 0xb7, 0xc5, 0x6d, 0x10, 0xcf, 0x83, 0xdc, 0x38, 0x0a, 0x6c, 0xef, 0xa4, 0x90, 0xb3, 0x4a, 0x0e, 0xd2, 0xdc, 0x69, 0xbb, 0x88, 0x58, 0x16, 0x2d, 0xb2, 0xfe, 0xa1, 0x16, 0x74, 0x70, 0x31, 0x70, 0x25, 0x0e, 0x11, 0x2e, 0x3e, 0x81, 0x35, 0xff, 0x39, 0x23, 0xb2, 0x7a, 0xb3, 0x2e, 0x99, 0xd9, 0x2c, 0x6b, 0xd9, 0xce, 0x48, 0x22, 0x71, 0xb2, 0x25, 0x66, 0x70, 0x17, 0x0a, 0xf1, 0x18, 0xeb, 0x70, 0x77, 0x35, 0x9e, 0xbb, 0xe7, 0x16, 0xb9, 0x59, 0x90, 0xb3, 0x38, 0x03, 0x8c, 0x17, 0x41, 0xdd, 0x74, 0x50, 0x2a, 0x17, 0x95, 0x4b, 0xf1, 0x9b, 0xfe, 0xbe, 0x65, 0x89, 0xa1, 0x0a, 0xfe, 0x47, 0xf5, 0xdb, 0xff, 0x4b, 0x35, 0x5a, 0x1e, 0xb4, 0x36, 0x92, 0x98, 0x75, 0x99, 0x43, 0x99, 0x50, 0x27, 0xe1, 0x7a, 0xcb, 0x03, 0x64, 0x55, 0x4f, 0x18, 0x10, 0x60, 0x14, 0x58, 0x30, 0x18, 0x71, 0x10, 0xa2, 0xe3, 0x87, 0xb0, 0xb1, 0xe9, 0xa0, 0xee, 0x51, 0x88, 0x08, 0x12, 0x24, 0xda, 0x83, 0xb9, 0xb1, 0xab, 0xc9, 0x9d, 0x90, 0x6e, 0xb0, 0x21, 0xec, 0x80, 0xfe, 0x11, 0x80, 0xda, 0x6f, 0xcb, 0xa7, 0x99, 0x3e, 0xc9, 0x9b, 0x75, 0xbf, 0x33, 0x10, 0x06, 0xca, 0x01, 0xd0, 0x99, 0x75, 0x63, 0x41, 0xed, 0x04, 0xfe, 0xf0, 0x6e, 0x3a, 0x0c, 0x30, 0x64, 0xf7, 0x31, 0x9e, 0x19, 0x43, 0x7c, 0x3b, 0x52, 0x30, 0x62, 0x7d, 0x07, 0xd1, 0xec, 0xa8, 0x50, 0x29, 0xaf, 0x67, 0x46, 0x88, 0xf5, 0x5e, 0x7d, 0x22, 0xcc, 0xdc, 0x4b, 0x9c, 0x31, 0x12, 0xa2, 0x18, 0xfc, 0xd3, 0x57, 0xc6, 0x60, 0x5f, 0xad, 0x41, 0x49, 0x8c, 0xdb, 0x62, 0xe8, 0xda, 0x05, 0x4e, 0x0f, 0x5a, 0x90, 0x3c, 0x6b, 0x06, 0x70, 0x18, 0xb0, 0x8e, 0x43, 0x49, 0xf2, 0xa6, 0x34, 0x96, 0xdb, 0xa7, 0x9c, 0xc2, 0xc3, 0xdf, 0xdd, 0x9f, 0x0b, 0x88, 0xcc, 0xb1, 0x4d, 0x57, 0x8c, 0x51, 0x3b, 0xba, 0x20, 0x53, 0xd0, 0xf5, 0x83, 0xf9, 0x7d, 0x4d, 0x7b, 0xae, 0x64, 0xc9, 0xc2, 0x09, 0x74, 0xcf, 0x6e, 0x79, 0x6a, 0x8c, 0x92, 0x9c, 0x16, 0x73, 0xd0, 0xaa, 0x0c, 0x8d, 0x3f, 0x00, 0xbb, 0x36, 0xd2, 0x8f, 0x7a, 0xa9, 0x5c, 0x30, 0x3a, 0x51, 0x9c, 0xd1, 0x25, 0x2f, 0xee, 0x16, 0x7d, 0xb1, 0x02, 0xa9, 0x5b, 0x2f, 0x18, 0x10, 0xc2, 0x5b, 0xf6, 0x13, 0x6e, 0x77, 0xd8, 0x8b, 0xc8, 0x3a, 0x3b, 0x75, 0x44, 0xb6, 0x9b, 0x8a, 0x31, 0x21, 0x4c, 0x25, 0x3f, 0xcd, 0x4e, 0x50, 0x2b, 0xe0, 0xd5, 0x49, 0x3b, 0x0c, 0xc8, 0x3b, 0xe0, 0x12, 0xb0, 0xf6, 0xff, 0xe1, 0xa9, 0xfd, 0xdb, 0x19, 0x06, 0x2a, 0x4c, 0x83, 0xff, 0xb2, 0x63, 0x13, 0x85, 0x06, 0xfc, 0xd5, 0x4c, 0x5a, 0x57, 0x34, 0x79, 0xe6, 0xc6, 0x20, 0x9b, 0x21, 0x0e, 0x50, 0x7c, 0x9f, 0xb4, 0x10, 0xa9, 0xa4, 0xa3, 0x3c, 0x43, 0x84, 0x16, 0x4c, 0x3d, 0xb3, 0x53, 0xc2, 0x12, 0xfd, 0x21, 0x32, 0xf8, 0x42, 0x69, 0x64, 0x9e, 0xd1, 0x42, 0x65, 0xbb, 0x86, 0x7c, 0x9b, 0xcb, 0xfd, 0xac, 0xdc, 0xe5, 0xba, 0xd6, 0xa9, 0x84, 0xca, 0x8e, 0x39, 0x2a, 0x9c, 0x69, 0x3e, 0x1a, 0x0d, 0xe7, 0xc9, 0xcd, 0xd0, 0x23, 0x2e, 0xfb, 0xcd, 0xf8, 0x63, 0x56, 0x51, 0x13, 0x63, 0x9f, 0xaa, 0x8c, 0x7e, 0x06, 0xc2, 0xdc, 0xff, 0x9d, 0x6a, 0x74, 0x6a, 0xd5, 0x9b, 0xb5, 0x70, 0x4a, 0xda, 0xc4, 0x39, 0xda, 0xa2, 0x31, 0x6e, 0x54, 0x38, 0xec, 0xd5, 0x82, 0xff, 0x78, 0xae, 0x8b, 0x92, 0x84, 0xbf, 0x69, 0x1e, 0x4c, 0x7e, 0x05, 0x31, 0x22, 0x8a, 0xcd, 0xd7, 0x93, 0xa6, 0x11, 0x34, 0xb9, 0x6b, 0x57, 0xbd, 0xe2, 0xa2, 0x66, 0xd5, 0x6e, 0x0a, 0x4f, 0xd4, 0x3b, 0xc6, 0x6c, 0x19, 0xcf, 0x6e, 0x4a, 0xeb, 0xbc, 0x0d, 0x51, 0x36, 0x5d, 0xcb, 0x52, 0xe9, 0xb1, 0xa5, 0x18, 0x2d, 0x90, 0x45, 0xfd, 0x94, 0x5a, 0x54, 0xa2, 0x5b, 0xbe, 0xbd, 0xd6, 0x66, 0xcf, 0x69, 0xba, 0x58, 0x24, 0xda, 0x20, 0x4d, 0x6b, 0x5f, 0x52, 0x5b, 0x35, 0x9e, 0xa8, 0x0b, 0x09, 0x1d, 0x80, 0x3f, 0x23, 0xb5, 0x0c, 0x25, 0xa9, 0x2e, 0x89, 0xf1, 0x42, 0x5a, 0xd1, 0x03, 0xbf, 0x79, 0xcf, 0x01, 0x8d, 0xab, 0x4d, 0x94, 0x5a, 0xce, 0xc1, 0x7f, 0x4c, 0x6c, 0x96, 0x34, 0xf5, 0x7c, 0xdb, 0x04, 0x15, 0xf3, 0x85, 0xa9, 0xd8, 0xb4, 0x8a, 0x5f, 0x14, 0x32, 0x53, 0x35, 0x47, 0x57, 0xd7, 0xa6, 0x95, 0x80, 0x50, 0x09, 0xcf, 0x90, 0x23, 0x4a, 0xd2, 0x63, 0x09, 0x80, 0xa9, 0xe2, 0xf8, 0xc7, 0x0d, 0x02, 0x39, 0xc1, 0xd1, 0x3a, 0x09, 0x04, 0x81, 0x10, 0x26, 0x0a, 0x6a, 0x4e, 0x56, 0xe4, 0x29, 0xdf, 0x82, 0x66, 0x35, 0x0c, 0x0e, 0x19, 0x17, 0x6f, 0x01, 0x24, 0x08, 0xf1, 0x0a, 0x81, 0x3b, 0x89, 0x7e, 0x9c, 0x4a, 0xac, 0xb7, 0xbc, 0x59, 0x2a, 0x43, 0xa9, 0x8a, 0xbd, 0x83, 0xdb, 0x89, 0x81, 0x57, 0xd7, 0x71, 0x10, 0x17, 0x7e, 0x2a, 0x8a, 0x2e, 0x23, 0x66, 0x69, 0x71, 0x3b, 0xad, 0x7c, 0x30, 0x82, 0x1e, 0xb5, 0xcc, 0xc6, 0xe7, 0xf5, 0x29, 0x37, 0xdf, 0xf3, 0x26, 0x1a, 0x9f, 0x63, 0x72, 0x91, 0x80, 0x10, 0x4e, 0x36, 0x1e, 0xf5, 0x3d, 0x05, 0xbd, 0x1d, 0xac, 0x97, 0x34, 0xec, 0x95, 0x21, 0x92, 0x2f, 0x9d, 0x1b, 0x0e, 0xfe, 0x60, 0x78, 0x78, 0x39, 0xf6, 0xe2, 0xad, 0x58, 0x33, 0x0e, 0x1a, 0xe9, 0x2e, 0x13, 0x1d, 0xe5, 0x36, 0xee, 0x8b, 0x25, 0x4d, 0x66, 0x3e, 0x71, 0x6e, 0x93, 0xcb, 0x1f, 0x67, 0xe7, 0xdd, 0x25, 0x21, 0x48, 0xee, 0xc2, 0xed, 0x2a, 0x3b, 0x68, 0x7b, 0x82, 0xb7, 0xea, 0xc2, 0xc0, 0xd4, 0x3f, 0xa7, 0xdd, 0x67, 0x43, 0xb5, 0x7a, 0xe9, 0x08, 0xab, 0x26, 0xa1, 0xae, 0xd1, 0x52, 0x3e, 0xd6, 0xee, 0x21, 0x09, 0xb7, 0xe2, 0xb8, 0x30, 0xa9, 0x20, 0x7a, 0xd9, 0x26, 0xbc, 0xe4, 0x60, 0xf1, 0x79, 0x1e, 0xea, 0xe8, 0xaa, 0xaf, 0x1e, 0x09, 0x0f, 0x3b, 0x5e, 0x7b, 0x1f, 0x25, 0xae, 0x83, 0x3c, 0x69, 0xb7, 0x8f, 0xed, 0x7e, 0x6d, 0xb5, 0xeb, 0x9c, 0x80, 0xee, 0x01, 0x7c, 0x54, 0xa9, 0x12, 0x2f, 0x42, 0xe5, 0xc0, 0x3a, 0x48, 0xa8, 0xa7, 0x00, 0x97, 0x8a, 0x1d, 0x03, 0x04, 0x06, 0xb4, 0x30, 0x79, 0x77, 0x27, 0x89, 0x3a, 0x25, 0xac, 0x8b, 0xde, 0x9b, 0x4f, 0x27, 0x3c, 0xa6, 0x70, 0x88, 0x61, 0x76, 0x3a, 0xfe, 0x4e, 0xba, 0xeb, 0xcb, 0xc6, 0x67, 0xd7, 0xb9, 0xed, 0xa5, 0x5e, 0x61, 0xe8, 0x50, 0x6f, 0x97, 0x73, 0x5b, 0x07, 0xfb, 0xd7, 0xac, 0x8c, 0xde, 0xcf, 0xec, 0x73, 0x7b, 0x8c, 0x84, 0xce, 0x35, 0x6a, 0x81, 0x54, 0xee, 0x2b, 0x3b, 0x01, 0xea, 0x29, 0x35, 0x6c, 0x09, 0x27, 0x14, 0xc0, 0x04, 0x93, 0xb4, 0x7e, 0x59, 0xd6, 0x8d, 0x00, 0xdd, 0x46, 0xa3, 0x08, 0x4e, 0x9f, 0x89, 0x81, 0xd8, 0x1e, 0xf2, 0xbc, 0x04, 0x4d, 0xa4, 0x41, 0xe7, 0xd7, 0x82, 0xa6, 0x90, 0x31, 0xfa, 0x91, 0xf6, 0xa7, 0x19, 0x35, 0xea, 0x09, 0x0a, 0xd2, 0x9c, 0x18, 0xd6, 0x3b, 0xb9, 0xfe, 0xfe, 0xcc, 0x9b, 0x69, 0xbb, 0x14, 0x78, 0xc5, 0xef, 0xa4, 0x8d, 0xd9, 0x46, 0xef, 0x47, 0x80, 0x1d, 0xf9, 0x3b, 0xd6, 0xc5, 0x0f, 0xee, 0xb5, 0x93, 0x0a, 0x21, 0x10, 0x77, 0xd1, 0x27, 0x51, 0xc2, 0xa9, 0xe7, 0x52, 0xa5, 0x1f, 0x66, 0x25, 0x80, 0xdb, 0x5d, 0x17, 0x02, 0xbb, 0x34, 0x1e, 0x46, 0x42, 0x32, 0x96, 0xdd, 0x7f, 0xa4, 0xac, 0xfc, 0x5a, 0xf5, 0x09, 0xe7, 0x92, 0x53, 0xeb, 0x88, 0xdc, 0x33, 0x88, 0x53, 0x68, 0xf4, 0x5f, 0xd7, 0xed, 0xa4, 0xb7, 0x88, 0x9f, 0x0c, 0x67, 0x86, 0xb9, 0x96, 0xc7, 0x0a, 0xe5, 0x6b, 0xac, 0x89, 0xb0, 0x31, 0x68, 0x4c, 0x9c, 0xf0, 0x55, 0xcb, 0x70, 0x53, 0x22, 0x8e, 0xca, 0xee, 0x33, 0xc6, 0x43, 0xff, 0xde, 0xdf, 0xe3, 0x30, 0x8a, 0xbe, 0x7c, 0x88, 0xf1, 0x3e, 0x29, 0xd6, 0x1b, 0x07, 0x43, 0xbd, 0x4b, 0xc8, 0x51, 0xe6, 0x8e, 0x17, 0x45, 0x98, 0xb9, 0x1f, 0xf9, 0xdb, 0xcd, 0x52, 0x52, 0xc2, 0x47, 0x12, 0xfc, 0x51, 0x57, 0x63, 0x3a, 0xbf, 0x7c, 0x2e, 0xd4, 0xb1, 0x09, 0x69, 0x39, 0x8d, 0xb7, 0x15, 0x2a, 0xcb, 0x89, 0xcb, 0x28, 0x67, 0xcf, 0xa7, 0x4a, 0x0b, 0xb8, 0x3d, 0x10, 0x30, 0xd5, 0x4a, 0xd9, 0xea, 0x42, 0x83, 0x4e, 0x2a, 0x8d, 0x38, 0xf9, 0xc8, 0xe8, 0x33, 0xa1, 0x09, 0xd9, 0xf0, 0x75, 0xde, 0xe3, 0xc2, 0x42, 0x8f, 0x49, 0xd8, 0x7c, 0x7f, 0x47, 0xfb, 0x0c, 0xc1, 0x2e, 0x66, 0x01, 0x09, 0x96, 0x0c, 0x56, 0x72, 0x66, 0x3e, 0x38, 0x4a, 0xb4, 0xcd, 0xc4, 0xd0, 0x4e, 0x82, 0xce, 0xac, 0x5f, 0x40, 0x3b, 0x59, 0x80, 0x84, 0xc6, 0x9b, 0x43, 0xc4, 0x9b, 0xd6, 0x4f, 0x91, 0x74, 0x3f, 0xdd, 0x78, 0xf0, 0xe5, 0xd8, 0xbe, 0x71, 0x21, 0xb7, 0x11, 0x05, 0x09, 0x77, 0x87, 0xd9, 0x06, 0xc9, 0x04, 0xc0, 0xb9, 0x2c, 0x59, 0xdb, 0x2b, 0xbc, 0x22, 0x17, 0xcb, 0xef, 0x93, 0xe8, 0xfb, 0x5c, 0x2a, 0x74, 0x70, 0x9f, 0x9d, 0x45, 0x0c, 0xe9, 0xec, 0xfe, 0x57, 0x44, 0x22, 0x1a, 0xc8, 0xb5, 0x9d, 0xbc, 0x8b, 0x75, 0x5d, 0x8d, 0x3d, 0xdb, 0xb1, 0x65, 0x01, 0x4c, 0x4a, 0xdd, 0x68, 0x06, 0x39, 0x57, 0x15, 0x3c, 0x4a, 0x1c, 0x1a, 0x29, 0x88, 0xfa, 0xe7, 0x68, 0x05, 0x9e, 0xc9, 0xc3, 0x95, 0x52, 0x51, 0x46, 0xb9, 0xf3, 0x14, 0xb2, 0x21, 0x99, 0xd4, 0xbf, 0x5e, 0x64, 0x58, 0xa9, 0x2f, 0x87, 0x84, 0x00, 0x4e, 0x8c, 0x6b, 0x86, 0xa7, 0xb6, 0x72, 0x40, 0xab, 0x49, 0xa7, 0x8f, 0x37, 0xc0, 0x3c, 0xbc, 0xc1, 0xb0, 0xce, 0x28, 0x2a, 0x40, 0xd7, 0x17, 0xcd, 0x18, 0x29, 0xf7, 0x40, 0xa9, 0xd4, 0x2b, 0xe5, 0x38, 0x59, 0xb7, 0xe2, 0xf3, 0xec, 0xe6, 0x3d, 0xa2, 0x2d, 0x70, 0x92, 0x73, 0x41, 0x3b, 0x37, 0xe4, 0x21, 0x6c, 0x88, 0x1c, 0xe3, 0xda, 0x08, 0x7d, 0xeb, 0xfb, 0xdb, 0x33, 0xaf, 0x0f, 0xad, 0x72, 0x06, 0x8a, 0x60, 0x46, 0x3d, 0x30, 0x03, 0xe4, 0x50, 0x8f, 0x2f, 0xf4, 0x33, 0xe3, 0x2b, 0x33, 0x2a, 0x31, 0x70, 0x79, 0x07, 0xc0, 0x62, 0xca, 0xdc, 0xaa, 0xba, 0x74, 0x9f, 0xac, 0xc0, 0xab, 0xa9, 0x5b, 0x8a, 0x2b, 0x40, 0xe9, 0x34, 0x85, 0x12, 0x42, 0x24, 0xdf, 0x2c, 0xaa, 0x38, 0xc2, 0x6f, 0x8c, 0x2c, 0x7a, 0x4c, 0x2e, 0xbd, 0x9c, 0x10, 0x5d, 0x1a, 0x16, 0xf5, 0xce, 0x96, 0x17, 0xf4, 0x96, 0xa7, 0x30, 0x05, 0xfa, 0x55, 0xfd, 0x31, 0xcc, 0xcc, 0xf0, 0x98, 0x51, 0x18, 0x10, 0x06, 0x5c, 0x33, 0x4e, 0xde, 0xb3, 0xf6, 0x90, 0x37, 0x6a, 0x03, 0x71, 0xe7, 0x3f, 0x21, 0x09, 0x10, 0x0f, 0xaa, 0xa2, 0x23, 0x5b, 0xf9, 0x7a, 0x47, 0xfa, 0x68, 0xf3, 0xcf, 0xae, 0xf2, 0x9a, 0x1d, 0xab, 0x8b, 0xac, 0x60, 0xe7, 0xbd, 0xbc, 0x1f, 0xfa, 0x8c, 0x93, 0x26, 0x8a, 0x89, 0x58, 0x4f, 0x0d, 0xf6, 0x70, 0x62, 0x96, 0xd5, 0x3b, 0x52, 0x53, 0xa0, 0x44, 0x8f, 0x1a, 0x51, 0x56, 0x68, 0xc3, 0xf0, 0xc6, 0xc3, 0x70, 0x64, 0xef, 0x92, 0x67, 0x42, 0x76, 0x96, 0xa1, 0xec, 0x05, 0x7f, 0x34, 0x3b, 0x8f, 0x09, 0x4a, 0xe7, 0xc4, 0x02, 0xcf, 0x51, 0xd4, 0x72, 0x5b, 0xa5, 0xae, 0xf6, 0xed, 0xfa, 0xb9, 0xf8, 0xfd, 0xd7, 0xd4, 0x61, 0xb6, 0x54, 0x0e, 0x9a, 0xbb, 0xc8, 0x94, 0x21, 0x67, 0x56, 0xe9, 0xbc, 0xcc, 0x88, 0x5e, 0xd6, 0x93, 0xfd, 0xb8, 0xdd, 0x22, 0xea, 0x5f, 0x4e, 0xdf, 0xf4, 0xf2, 0x8c, 0x9e, 0xa1, 0xf8, 0x49, 0x1f, 0x42, 0x0e, 0x11, 0x83, 0xc6, 0x83, 0xa4, 0x23, 0xd6, 0x0d, 0x14, 0x3e, 0x8b, 0x01, 0xc6, 0xec, 0xfb, 0x4b, 0xc8, 0xe2, 0x51, 0xbf, 0x31, 0xcc, 0x2b, 0xfb, 0x16, 0x3f, 0x9e, 0x55, 0x98, 0x95, 0x86, 0x65, 0xa4, 0x22, 0xe2, 0xc9, 0x72, 0x97, 0x69, 0x0d, 0x2e, 0x5d, 0x87, 0x6a, 0x8e, 0x8a, 0x1b, 0xc3, 0xbd, 0x19, 0xcd, 0xd2, 0xf9, 0x5b, 0xbf, 0xd1, 0x32, 0x11, 0xdc, 0xdd, 0xd3, 0x9b, 0x41, 0x85, 0x7c, 0x38, 0x41, 0x6f, 0x74, 0x4b, 0x0c, 0xc0, 0x17, 0x75, 0xee, 0x55, 0x5f, 0xeb, 0x8e, 0xb7, 0x9d, 0xbf, 0x35, 0xda, 0xea, 0x07, 0x3c, 0xe5, 0x7f, 0x22, 0x1c, 0x4d, 0x22, 0x1d, 0xe4, 0x4b, 0xc7, 0xe5, 0x6a, 0x59, 0xdb, 0x9f, 0xb2, 0x79, 0xc1, 0xc9, 0x20, 0x97, 0xe5, 0xcf, 0x2f, 0xc1, 0xb7, 0x5d, 0xb1, 0xbf, 0x6d, 0xca, 0x7a, 0x34, 0x1d, 0x39, 0x88, 0x1c, 0x2d, 0x83, 0xd5, 0xf6, 0xef, 0x4c, 0xce, 0xe7, 0x2e, 0x35, 0xcd, 0xab, 0x7d, 0x64, 0xd6, 0x57, 0x93, 0x66, 0x7e, 0xab, 0x5b, 0xf2, 0xc9, 0x49, 0xd8, 0x67, 0x97, 0x01, 0x72, 0x5a, 0xf2, 0xfa, 0x7d, 0x27, 0x56, 0x88, 0x9f, 0xb0, 0xc1, 0x3c, 0x2c, 0x9d, 0x5a, 0x5f, 0x96, 0x30, 0xee, 0x3a, 0x90, 0x74, 0xb0, 0x9f, 0x30, 0x9b, 0x98, 0x86, 0xff, 0x15, 0x0e, 0xad, 0x55, 0x23, 0xbf, 0xc4, 0xb3, 0x21, 0xfc, 0x1d, 0x45, 0x5c, 0x12, 0x78, 0xa4, 0x63, 0xe2, 0x05, 0xda, 0x25, 0x82, 0xbb, 0x7f, 0xa3, 0x1f, 0xc7, 0x2b, 0x1c, 0xbd, 0x6c, 0x34, 0xe0, 0xc9, 0xf1, 0x44, 0x70, 0xec, 0x13, 0xb9, 0x73, 0x1c, 0x82, 0x45, 0x99, 0xe6, 0xb1, 0xf0, 0x9f, 0xfa, 0x79, 0xa7, 0x6f, 0x3e, 0xf4, 0xd1, 0x18, 0x90, 0x4b, 0xd2, 0xdb, 0x5a, 0x0f, 0x9f, 0x5d, 0x97, 0x67, 0x52, 0x19, 0x19, 0x3c, 0x1c, 0x74, 0x40, 0x8c, 0x7b, 0xbf, 0xfe, 0x02, 0x26, 0x66, 0x46, 0xab, 0x3f, 0x46, 0x94, 0x56, 0x47, 0x87, 0x11, 0xa0, 0x3d, 0x46, 0xfa, 0xae, 0xc9, 0x78, 0x95, 0x36, 0x99, 0x98, 0xff, 0xe1, 0x59, 0x74, 0xc8, 0xa2, 0x79, 0x61, 0x7e, 0x42, 0xed, 0x9a, 0x2f, 0x13, 0x1b, 0x8e, 0x6b, 0x25, 0x53, 0x4d, 0xbf, 0xf8, 0x6a, 0x40, 0x97, 0x5c, 0x52, 0x6b, 0xe8, 0x09, 0x5f, 0x3d, 0x4f, 0xfe, 0x8f, 0xdf, 0x66, 0x10, 0x49, 0xd7, 0x05, 0x56, 0x9e, 0x32, 0x74, 0x3c, 0x01, 0x1e, 0x50, 0x7d, 0x1a, 0xae, 0xed, 0xcc, 0x07, 0x6f, 0x9c, 0x3b, 0x37, 0x9e, 0x82, 0x0f, 0xa5, 0x6e, 0x1e, 0x18, 0x89, 0xda, 0xaa, 0xdb, 0x1a, 0xd4, 0xc7, 0x30, 0xd1, 0x54, 0x42, 0x48, 0x08, 0xeb, 0x2f, 0x26, 0xd2, 0x09, 0x11, 0xa7, 0x56, 0x27, 0xb0, 0x91, 0x9d, 0x16, 0x54, 0x6c, 0x6c, 0x50, 0x56, 0x7e, 0xd2, 0xd8, 0xf9, 0x83, 0xe8, 0xa3, 0x8d, 0x52, 0x0e, 0x42, 0x2f, 0xb5, 0x87, 0xd7, 0x4b, 0x9a, 0xf5, 0x91, 0xf9, 0x41, 0x89, 0x79, 0x55, 0xfe, 0x14, 0x7b, 0x0a, 0xd8, 0xe3, 0x83, 0xad, 0x02, 0x26, 0x3c, 0x4d, 0x08, 0xe4, 0x47, 0x41, 0xc9, 0x36, 0x12, 0xdc, 0xc3, 0x53, 0x7e, 0xb6, 0xf7, 0xed, 0x6c, 0x3f, 0x4a, 0x97, 0x98, 0x1d, 0xbe, 0x4e, 0x12, 0x58, 0xc3, 0x1c, 0x1b, 0xfb, 0xd2, 0xf5, 0x16, 0x80, 0xd4, 0xa9, 0x0b, 0xab, 0x86, 0xa5, 0xd4, 0xd8, 0x7f, 0x3f, 0xc4, 0x71, 0xbb, 0x69, 0xc6, 0xd9, 0x9b, 0x72, 0x95, 0x6d, 0xf9, 0x79, 0x52, 0x6b, 0xde, 0x65, 0x97, 0xe5, 0x5e, 0xd1, 0xc1, 0xbd, 0x94, 0x53, 0xed, 0xf4, 0x4e, 0x6c, 0xd4, 0x7f, 0x3e, 0xca, 0xd4, 0x0e, 0xb9, 0x9a, 0x56, 0x73, 0x56, 0xb2, 0xde, 0x4c, 0x3c, 0x1c, 0xdf, 0x26, 0x14, 0x67, 0xb4, 0x67, 0x35, 0x54, 0x4c, 0x45, 0x5e, 0x37, 0x55, 0xfd, 0x3b, 0x65, 0x5d, 0xc7, 0xdd, 0x4d, 0xd5, 0x8b, 0x32, 0x43, 0xf7, 0xfc, 0xd6, 0xbb, 0xb5, 0x98, 0x3d, 0x49, 0xe1, 0xac, 0x40, 0xc9, 0xd1, 0xf5, 0x7b, 0x5f, 0x6d, 0x46, 0xea, 0x15, 0xaf, 0x3d, 0x02, 0xbb, 0xe4, 0x98, 0x47, 0xd3, 0x70, 0xc5, 0xa8, 0x72, 0x8e, 0xae, 0xd8, 0x23, 0x2d, 0xcf, 0x50, 0x5e, 0xa6, 0x7d, 0xbd, 0x81, 0xd4, 0x11, 0x12, 0xbf, 0x7f, 0x37, 0xee, 0x5d, 0x39, 0x4c, 0x0f, 0x92, 0xb0, 0x7e, 0x20, 0x3c, 0x71, 0x4e, 0x92, 0x33, 0x46, 0xd6, 0xb2, 0xbf, 0xa4, 0x57, 0xcb, 0x0d, 0x4e, 0xe8, 0x54, 0x07, 0x5b, 0x01, 0x15, 0x46, 0x61, 0xcc, 0x7d, 0x9f, 0xa5, 0xab, 0x27, 0x34, 0x16, 0x45, 0x9c, 0x82, 0x0e, 0x60, 0x97, 0x44, 0x8b, 0x0e, 0x36, 0x29, 0x58, 0x10, 0x07, 0x97, 0x83, 0x33, 0x78, 0x27, 0xff, 0xee, 0xa0, 0x73, 0x3f, 0xf4, 0x06, 0xec, 0x56, 0x11, 0xfc, 0xff, 0xc6, 0xee, 0x81, 0x0a, 0xd5, 0x93, 0xb0, 0x41, 0x4e, 0xd3, 0xbf, 0xf7, 0xb8, 0xa5, 0x81, 0x4c, 0xee, 0x7f, 0xdb, 0x48, 0x39, 0xed, 0x98, 0x4e, 0x8c, 0xb9, 0xc6, 0x72, 0x85, 0xa2, 0x91, 0x7d, 0x2d, 0x74, 0x96, 0xae, 0x8d, 0x4d, 0x8a, 0x77, 0xf2, 0xe6, 0xcc, 0x20, 0x7e, 0x40, 0x31, 0x8a, 0xd6, 0xd1, 0xc4, 0xef, 0x74, 0x7a, 0x5b, 0x2c, 0x74, 0x02, 0x3b, 0xe1, 0x12, 0x23, 0x8b, 0x22, 0x6b, 0xef, 0x99, 0x65, 0xa7, 0x62, 0x27, 0x11, 0xcd, 0x7d, 0xc2, 0xf5, 0x23, 0x3b, 0xb4, 0xb2, 0x85, 0xab, 0x01, 0x97, 0x51, 0x8e, 0xd6, 0x78, 0x23, 0xeb, 0x9c, 0x93, 0x0a, 0xb6, 0xa0, 0x7f, 0x25, 0x37, 0x33, 0xc6, 0x42, 0x0c, 0x73, 0x8d, 0xec, 0x34, 0x20, 0xa1, 0x01, 0x6c, 0xda, 0xe2, 0x3c, 0xe4, 0x2a, 0xd9, 0xaf, 0xa6, 0xd7, 0x6d, 0x70, 0x33, 0x93, 0xfa, 0x74, 0x39, 0xab, 0xa1, 0x4f, 0xfb, 0x0c, 0xa1, 0x9e, 0x67, 0x53, 0x77, 0x95, 0x60, 0xde, 0x01, 0x8b, 0xb0, 0x60, 0x95, 0x6d, 0x87, 0xa2, 0xc3, 0xbe, 0xb6, 0xbe, 0x97, 0xe9, 0x71, 0x33, 0x5f, 0x44, 0x20, 0x15, 0x06, 0x89, 0x54, 0x8d, 0x72, 0x2e, 0x93, 0x3b, 0x57, 0xd5, 0x15, 0x21, 0x1a, 0x00, 0xc4, 0x7b, 0xec, 0xa0, 0x75, 0xcf, 0x1d, 0x15, 0x1a, 0x18, 0x9b, 0xd8, 0xb1, 0xd8, 0xbf, 0x59, 0x4b, 0xf4, 0xe3, 0x37, 0x93, 0x3a, 0xbe, 0x1f, 0x45, 0x0b, 0xc1, 0x5f, 0xbd, 0x6a, 0x72, 0x78, 0x9d, 0xb7, 0x5a, 0xd4, 0xa7, 0xa5, 0xd9, 0x83, 0x3d, 0xda, 0x48, 0x49, 0x20, 0x87, 0xd8, 0x5a, 0xbf, 0x08, 0x6d, 0xc8, 0xc9, 0x96, 0x54, 0xc1, 0xc9, 0xc2, 0x27, 0xbb, 0xbe, 0x08, 0xae, 0x22, 0xdd, 0xb2, 0xb6, 0x56, 0xa0, 0x78, 0xb4, 0xa1, 0xe8, 0x27, 0xd5, 0x5f, 0x3a, 0xb4, 0xd5, 0xdf, 0xc3, 0x01, 0x5b, 0x79, 0xd6, 0xee, 0x82, 0x43, 0x32, 0xfc, 0x57, 0x2d, 0xd2, 0x61, 0xb3, 0xcd, 0xe6, 0xe6, 0x12, 0xd5, 0xa9, 0x74, 0x63, 0x45, 0xa6, 0xac, 0x34, 0x6e, 0x4f, 0x7f, 0x67, 0x5a, 0xda, 0x47, 0xec, 0x69, 0x13, 0xff, 0x78, 0x2b, 0xc6, 0x93, 0xe8, 0x49, 0x8f, 0x00, 0xa9, 0x49, 0xfb, 0x34, 0x06, 0xbb, 0x30, 0x47, 0x1d, 0x81, 0xbc, 0x24 }, { 0x86, 0x44, 0x65, 0x48, 0x98, 0x02, 0x89, 0x94,0xe2, 0xba, 0xcd, 0xbd, 0x38, 0x31, 0xa1, 0xed }, }, { 24, 16, 20, { 0x48, 0xb8, 0x2b, 0x72, 0xfc, 0x81, 0xbe, 0x86, 0x86, 0x0f, 0x72, 0x06, 0x5e, 0xfa, 0x62, 0x18, 0x6f, 0x9d, 0xa5, 0x96, 0xbd, 0xf9, 0x51, 0x58 }, { 0x24, 0xda, 0x67, 0xae, 0xf7, 0x4b, 0xe3, 0x33, 0x85, 0x89, 0xcc, 0xb6 }, { 0xf8, 0x6a, 0x57, 0xa3, 0x0c, 0x06, 0xef, 0xb1, 0x0e, 0xcb, 0xeb, 0x3d, 0x5a, 0x9d, 0x97, 0xb5 }, { 0xc1, 0xf7, 0xf5, 0xc8, 0xf8, 0xcc, 0x51, 0x37, 0xa5, 0x39, 0x91, 0x94, 0x1f, 0x38, 0x8f, 0xfd, 0x2b, 0x27, 0xf0, 0xdd }, { 0x4b, 0xe5, 0x8c, 0xd0, 0x63, 0x78, 0xc0, 0x38, 0x78, 0xd4, 0xf1, 0x65, 0x94, 0x43, 0xc5, 0xd1 }, { 0x84, 0xdd, 0x00, 0xb8, 0xb0, 0x3a, 0xcb, 0x92, 0x19, 0xec, 0x51, 0x16, 0xe3, 0xde, 0x73, 0x62 } }, # endif /* !USE_LIBSODIUM_AES_GCM */ { 32, 32, 16, { 0x27, 0x2d, 0x16, 0x49, 0xa3, 0xdd, 0x80, 0x4d, 0xe0, 0x96, 0x2d, 0x3e, 0x07, 0x06, 0x4a, 0x70, 0x54, 0xc0, 0x0a, 0x62, 0x34, 0xab, 0x1b, 0x0c, 0xdc, 0xf6, 0x85, 0xab, 0x39, 0x48, 0x37, 0xe5 }, { 0x95, 0x5b, 0x58, 0x97, 0xf6, 0xb9, 0x80, 0x6b, 0xbe, 0xc5, 0xc3, 0x3e }, { 0x36, 0xe5, 0x7c, 0x29, 0xc0, 0x8c, 0x51, 0xad, 0x7f, 0xa9, 0x1c, 0x04, 0x16, 0xf9, 0x76, 0xcf, 0xd0, 0x11, 0x78, 0x0e, 0xb4, 0x4c, 0xc5, 0xab, 0xd3, 0x4c, 0x7b, 0x43, 0x1b, 0x09, 0x3b, 0x8d }, { 0x33, 0xe6, 0x18, 0xec, 0xbb, 0xe5, 0xeb, 0x05, 0x66, 0xdf, 0x21, 0xc3, 0xc3, 0x4b, 0x7e, 0x25 }, { 0xcd, 0x6a, 0xeb, 0x34, 0x50, 0x81, 0xdc, 0x0b, 0xb2, 0xc8, 0xb4, 0xd1, 0x9b, 0x28, 0x06, 0x58, 0xfb, 0x87, 0xc0, 0xf2, 0xbd, 0x0f, 0x4c, 0x9d, 0xa6, 0x94, 0xdc, 0x1f, 0xee, 0xb3, 0x2f, 0x4e }, { 0xdd, 0x37, 0xea, 0xc6, 0xbd, 0x6a, 0x4d, 0x36, 0x18, 0x24, 0x17, 0x38, 0x77, 0x97, 0x35, 0xd7 } } }; /* Test GCM mode AES */ for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { # ifndef USE_CL_GCM_GIV if (tests[i].keylen * 8 == 192) { continue; /* Skip AES-192 as some impl do not support it. */ } # endif /* USE_CL_GCM_GIV */ if (i == 1) { _psTraceInt(" AES-GCM-%d long known vector encrypt test... ", tests[i].keylen * 8); } else { _psTraceInt(" AES-GCM-%d known vector encrypt test... ", tests[i].keylen * 8); } psAesInitGCM(&eCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&eCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); psAesEncryptGCM(&eCtx, tests[i].pt, ciphertext, tests[i].ptlen); psAesGetGCMTag(&eCtx, 16, tag); if ((Memcmp(ciphertext, tests[i].ct, tests[i].ptlen) != 0) || (Memcmp(tag, tests[i].tag, 16) != 0)) { Printf("FAILED: memcmp mismatch\n"); res = PS_FAILURE; } else { Printf("PASSED\n"); } if (i == 1) { _psTraceInt(" AES-GCM-%d long known vector random encrypt test... ", tests[i].keylen * 8); } else { _psTraceInt(" AES-GCM-%d known vector random encrypt test... ", tests[i].keylen * 8); } Memcpy(iv, tests[i].iv, 12); psAesInitGCM(&eCtx, tests[i].key, tests[i].keylen); res |= psAesReadyGCMRandomIV(&eCtx, iv, tests[i].aad, tests[i].aadlen, NULL); if (res != PS_SUCCESS) { Memset(ciphertext_rand, 0, sizeof ciphertext_rand); } else { if (tests[i].ptlen > 1024) { /* Try multipart */ psAesEncryptGCM(&eCtx, tests[i].pt, ciphertext_rand, 1024); psAesEncryptGCM(&eCtx, tests[i].pt + 1024, ciphertext_rand + 1024, tests[i].ptlen - 1024); } else { psAesEncryptGCM(&eCtx, tests[i].pt, ciphertext_rand, tests[i].ptlen); } psAesGetGCMTag(&eCtx, 16, tag); } if ((tests[i].ptlen >= 16 && Memcmp(ciphertext_rand, tests[i].ct, tests[i].ptlen) == 0) || (Memcmp(tag, tests[i].tag, 16) == 0)) { Printf("FAILED: Random IV failed or not used.\n"); res = PS_FAILURE; } else { psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, iv, tests[i].aad, tests[i].aadlen); if (psAesDecryptGCM2(&dCtx, ciphertext_rand, plaintext_rand, tests[i].ptlen, tag, 16) != PS_SUCCESS || Memcmp(plaintext_rand, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: psAesDecryptGCM2 failed\n"); res = PS_FAILURE; } else { # ifdef USE_VERBOSE_RANDOM_GCM Printf("PASSED [iv=%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x]\n", iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7], iv[8], iv[9], iv[10], iv[11]); # else Printf("PASSED\n"); # endif } } psAesClearGCM(&eCtx); # ifndef USE_ONLY_DECRYPT_GCM_WITH_TAG _psTraceInt(" AES-GCM-%d known vector decrypt (tagless) test... ", tests[i].keylen * 8); psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); # ifdef USE_LIBSODIUM_AES_GCM /* TODO - libsodium cipher text must include the tag */ unsigned char *cipherTextAuthData; cipherTextAuthData = psMalloc(NULL, tests[i].ptlen + 16); Memcpy(cipherTextAuthData, tests[i].ct, tests[i].ptlen); Memcpy(cipherTextAuthData + tests[i].ptlen, tests[i].tag, 16); if (psAesDecryptGCM(&dCtx, cipherTextAuthData, tests[i].ptlen + 16, plaintext, tests[i].ptlen) != PS_SUCCESS) { Printf("FAILED: authentication failed\n"); } else if (Memcmp(plaintext, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: data mismatch\n"); } else { Printf("PASSED\n"); } psFree(cipherTextAuthData, NULL); # else psAesDecryptGCMtagless(&dCtx, tests[i].ct, plaintext, tests[i].ptlen); Memset(tag, 0x0, 16); psAesGetGCMTag(&dCtx, 16, tag); if ((Memcmp(plaintext, tests[i].pt, tests[i].ptlen) != 0) || (Memcmp(tag, tests[i].tag, 16) != 0)) { Printf("FAILED: memcmp mismatch\n"); res = PS_FAILURE; } else { Printf("PASSED\n"); } # endif psAesClearGCM(&dCtx); Memset(tag, 0x0, 16); Memset(plaintext, 0x0, 32); # endif /* !defined USE_ONLY_DECRYPT_GCM_WITH_TAG */ # ifndef USE_LIBSODIUM_AES_GCM _psTraceInt(" AES-GCM-%d known vector decrypt2 test... ", tests[i].keylen * 8); psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); if (psAesDecryptGCM2(&dCtx, tests[i].ct, plaintext, tests[i].ptlen, tests[i].tag, 16) != PS_SUCCESS || Memcmp(plaintext, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: psAesDecryptGCM2 failed\n"); res = PS_FAILURE; } else { Printf("PASSED\n"); } psAesClearGCM(&dCtx); Memset(plaintext, 0x0, 32); # endif /* !defined USE_LIBSODIUM_AES_GCM */ for (l = 0; l < (int32) sizeof(taglen); l++) { _psTraceInt(tagmsg[l], tests[i].keylen * 8); Memset(plaintext, 0x11, sizeof(plaintext)); Memset(ciphertext_with_tag, 0x22, sizeof(ciphertext_with_tag)); Memcpy(ciphertext_with_tag, tests[i].ct, tests[i].ptlen); Memcpy(ciphertext_with_tag + tests[i].ptlen, tests[i].tag, taglen[l]); psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); if (psAesDecryptGCM(&dCtx, ciphertext_with_tag, tests[i].ptlen + taglen[l], plaintext, tests[i].ptlen) == PS_SUCCESS) { if (Memcmp(plaintext, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: memcmp mismatch\n"); res = PS_FAILURE; } else { Printf("PASSED\n"); } } else { Printf("FAILED: tag verify failure\n"); res = PS_FAILURE; } } for (l = 0; l < (int32) sizeof(taglen); l++) { _psTraceInt(tagmsg2[l], tests[i].keylen * 8); Memset(plaintext, 0x11, sizeof(plaintext)); Memset(ciphertext_with_tag, 0x22, sizeof(ciphertext_with_tag)); Memcpy(ciphertext_with_tag, tests[i].ct, tests[i].ptlen); Memcpy(ciphertext_with_tag + tests[i].ptlen, tests[i].tag, taglen[l]); ciphertext_with_tag[tests[i].ptlen + taglen[l] - 1]++; psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); if (psAesDecryptGCM(&dCtx, ciphertext_with_tag, tests[i].ptlen + taglen[l], plaintext, tests[i].ptlen) != PS_SUCCESS) { psAesClearGCM(&dCtx); psAesInitGCM(&dCtx, tests[i].key, tests[i].keylen); psAesReadyGCM(&dCtx, tests[i].iv, tests[i].aad, tests[i].aadlen); if (psAesDecryptGCM2(&dCtx, tests[i].ct, plaintext, tests[i].ptlen, ciphertext_with_tag + tests[i].ptlen, taglen[l]) != PS_SUCCESS) { Printf("PASSED\n"); } else { Printf("FAILED: verify accepts invalid tag (%s)\n", "psAesDecryptGCM2"); res = PS_FAILURE; } } else { Printf("FAILED: verify accepts invalid tag (%s)\n", "psAesDecryptGCM"); res = PS_FAILURE; } } } return res; } # endif /* USE_AES_GCM */ # ifdef USE_AES_CTR int32 psAesTestCTR(void) { static struct { int32 keylen, msglen; unsigned char key[32], IV[16], pt[64], ct[64]; } tests[] = { /* 128-bit key, 16-byte pt */ { 16, 16, { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, }, /* 128-bit key, 36-byte pt */ { 16, 36, { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }, { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x00 }, { 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, 0x20, 0x21, 0x22, 0x23 }, { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, 0x25, 0xB2, 0x07, 0x2F }, }, }; int err, x; unsigned char buf[64]; psAesCtr_t ctr; for (x = 0; x < (int) (sizeof(tests) / sizeof(tests[0])); x++) { _psTraceInt(" AES-CTR-%d known vector test... ", tests[x].keylen * 8); if ((err = psAesInitExCTR(&ctr, tests[x].IV, tests[x].key, tests[x].keylen, CTR_COUNTER_BIG_ENDIAN | LTC_CTR_RFC3686, PS_AES_ENCRYPT)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesInitExCTR %d\n", err); return err; } psAesEncryptCTR(&ctr, (unsigned char *) tests[x].pt, buf, tests[x].msglen); if (Memcmp(buf, tests[x].ct, tests[x].msglen) != 0) { _psTrace("FAILED: memcmp\n"); } else { _psTrace("PASSED\n"); } psAesClearCTR(&ctr); } return PS_SUCCESS; } # endif /* USE_AES_CTR */ # ifdef USE_AES_CMAC int32 psAesTestCmac(void) { int32 err; static struct { int32 keylen, ptlen; unsigned char key[32], pt[64], ct[16]; } tests[] = { { 16, 16, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } }, { 16, 40, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } }, { 16, 64, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } }, { 24, 16, { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 } }, { 32, 40, { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, { 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6 } } }; int32 i; unsigned char cmac[16]; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" AES CMAC %d known vector test... ", tests[i].keylen * 8); if ((err = psCmacGenerate(NULL, tests[i].key, tests[i].keylen, tests[i].pt, tests[i].ptlen, cmac)) != PS_SUCCESS) { _psTraceInt("FAILED: psCmacGenerate %d\n", err); return err; } if (Memcmp(cmac, tests[i].ct, 16) != 0) { _psTrace("FAILED: memcmp\n"); } else { _psTrace("PASSED\n"); } } return 0; } # endif /* USE_AES_CMAC */ # ifdef USE_AES_WRAP int32 psAesTestWrap(void) { int32 err; static struct { int32 keylen, ptlen; unsigned char key[32], pt[32], ct[32]; } tests[] = { { 16, 16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, { 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 } }, { 24, 16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, { 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d } }, { 32, 16, { 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 }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, { 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 } } }; int32_t i; uint32_t woutlen, uoutlen; unsigned char unwrapped[32]; unsigned char wrapped[32]; for (i = 0; i < (uint32_t) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" AES KEY WRAP %d known vector test... ", tests[i].keylen * 8); if ((err = psAesWrap(tests[i].key, tests[i].keylen, tests[i].pt, tests[i].ptlen, wrapped, &woutlen)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesWrap %d\n", err); return err; } if ((err = psAesUnwrap(tests[i].key, tests[i].keylen, wrapped, woutlen, unwrapped, &uoutlen)) != PS_SUCCESS) { _psTraceInt("FAILED: psAesWrap %d\n", err); return err; } if (Memcmp(wrapped, tests[i].ct, woutlen) != 0 || Memcmp(unwrapped, tests[i].pt, uoutlen) != 0) { _psTrace("FAILED: memcmp\n"); } else { _psTrace("PASSED\n"); } } return 0; } # endif /* USE_AES_WRAP */ #endif /* USE_AES */ #if 0 static psAesHmacPerf(void) { /* Time AES-CBC encryption and decryption of AES_KB of data */ useHmac = 0; aesTag = "AES-CBC"; L_CBC_TIMING: # ifdef USE_AESNI_CRYPTO Printf("Timing %s with %d KiB of data (aes-ni)\n", aesTag, AES_KB); # else Printf("Timing %s with %d KiB of data\n", aesTag, AES_KB); # endif buf = psMalloc(pool, 1024 + 20); for (keysize = 16; keysize <= 32; keysize += 16) { _psTraceInt("AES-%d Key\n", keysize == 16 ? 128 : 256); for (i = 0; i < 1024; i++) { buf[i] = (unsigned char) (i & 0xFF); } Memset(iv, 0x1, 16); Memset(cbckey, 0x2, keysize); Memset(plaintext, 0x3, 16); Memset(hmackey, 0x4, 20); hmackeylen = 20; psAesInit(&encryptCtx, iv, cbckey, keysize); psGetTime(&start, NULL); for (k = 0; k < AES_KB; k++) { if (useHmac) { psHmacSha1(hmackey, hmackeylen, buf, 1024, buf + 1024, hmackey, &hmackeylen); } if (psAesEncrypt(&encryptCtx, buf, buf, 1024) != 1024) { Printf("ERROR LINE %d\n", __LINE__); return PS_FAILURE; } } psGetTime(&end, NULL); Printf("%s: encrypt %u msecs\n", aesTag, psDiffMsecs(start, end, NULL)); if (buf[0] == 0 && buf[1] == 1 && buf[2] == 2 && buf[3] == 3) { return PS_FAILURE; } psAesInit(&decryptCtx, iv, cbckey, keysize); psGetTime(&start, NULL); for (k = 0; k < AES_KB; k++) { if (useHmac) { psHmacSha1(hmackey, hmackeylen, buf, 1024, buf + 1024, hmackey, &hmackeylen); } if (psAesDecrypt(&decryptCtx, buf, buf, 1024) != 1024) { return PS_FAILURE; } } psGetTime(&end, NULL); Printf("%s: decrypt %u msecs\n", aesTag, psDiffMsecs(start, end, NULL)); } psFree(buf, pool); if (useHmac == 0) { useHmac = 1; aesTag = "AES-CBC-SHA-HMAC"; goto L_CBC_TIMING; } return PS_SUCCESS; } #endif /* 0 */ #ifdef USE_CHACHA20_POLY1305_IETF # define TEST_TEXT_MAXLEN 128 # define TEST_AAD_MAXLEN 32 # ifdef USE_LIBSODIUM_CHACHA20_POLY1305_IETF # define TEST_TAG_LEN crypto_aead_chacha20poly1305_IETF_ABYTES # define TEST_KEY_LEN crypto_aead_chacha20poly1305_IETF_KEYBYTES # define TEST_IV_LEN crypto_aead_chacha20poly1305_IETF_NPUBBYTES # else # define TEST_TAG_LEN 16 # define TEST_KEY_LEN 32 # define TEST_IV_LEN 12 # endif int32 psChacha20Poly1305IetfTest(void) { int32 i; psChacha20Poly1305Ietf_t eCtx, dCtx; unsigned char ciphertext[TEST_TEXT_MAXLEN]; unsigned char plaintext[TEST_TEXT_MAXLEN]; unsigned char plaintext2[TEST_TEXT_MAXLEN]; unsigned char ciphertext_tag[TEST_TEXT_MAXLEN + TEST_TAG_LEN]; unsigned char tag[TEST_TAG_LEN]; psResSize_t sz1; psResSize_t sz2; static struct { int32 keylen, ptlen, aadlen; unsigned char key[TEST_KEY_LEN], iv[TEST_IV_LEN], pt[TEST_TEXT_MAXLEN], aad[TEST_AAD_MAXLEN], ct[TEST_TEXT_MAXLEN], tag[TEST_TAG_LEN]; } tests[] = { { TEST_KEY_LEN, 114, 12, { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f }, /* IV */ { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 }, /* pt */ { 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e }, /* aad */ { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }, /* ct */ { 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16 }, /* tag */ { 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 } }, { TEST_KEY_LEN, 114, 0, { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f }, /* IV */ { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 }, /* pt */ { 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e }, /* aad */ { "" }, /* ct */ { 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16 }, /* tag */ { 0x6a, 0x23, 0xa4, 0x68, 0x1f, 0xd5, 0x94, 0x56, 0xae, 0xa1, 0xd2, 0x9f, 0x82, 0x47, 0x72, 0x16 } } }; /* Test AEAD CHACHA20-POLY1305 */ for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" CHACHA20-POLY1305-%d " "IETF " "known vector encrypt test... ", tests[i].keylen * 8); psChacha20Poly1305IetfInit(&eCtx, tests[i].key); sz1 = psChacha20Poly1305IetfEncryptDetached(&eCtx, tests[i].pt, tests[i].ptlen, tests[i].iv, tests[i].aad, tests[i].aadlen, ciphertext, tag); sz2 = psChacha20Poly1305IetfEncrypt(&eCtx, tests[i].pt, tests[i].ptlen, tests[i].iv, tests[i].aad, tests[i].aadlen, ciphertext_tag); if (sz1 != tests[i].ptlen || Memcmp(ciphertext, tests[i].ct, tests[i].ptlen) != 0 || Memcmp(tag, tests[i].tag, TEST_TAG_LEN) != 0) { Printf("FAILED: memcmp mismatch (psChacha20Poly1305IetfEncryptDetached)\n"); } else if (sz2 != tests[i].ptlen + TEST_TAG_LEN || Memcmp(ciphertext_tag, tests[i].ct, tests[i].ptlen) != 0 || Memcmp(ciphertext_tag + tests[i].ptlen, tests[i].tag, TEST_TAG_LEN) != 0) { Printf("FAILED: memcmp mismatch (psChacha20Poly1305IetfEncrypt)\n"); } else { Printf("PASSED\n"); } psChacha20Poly1305IetfClear(&eCtx); _psTraceInt(" CHACHA20-POLY1305-%d " "IETF " "known vector decrypt test... ", tests[i].keylen * 8); psChacha20Poly1305IetfInit(&dCtx, tests[i].key); /* Cipher text must include the tag */ unsigned char *cipherTextAuthData; cipherTextAuthData = psMalloc(NULL, tests[i].ptlen + TEST_TAG_LEN); Memcpy(cipherTextAuthData, tests[i].ct, tests[i].ptlen); Memcpy(cipherTextAuthData + tests[i].ptlen, tests[i].tag, TEST_TAG_LEN); sz1 = psChacha20Poly1305IetfDecrypt( &dCtx, cipherTextAuthData, tests[i].ptlen + TEST_TAG_LEN, tests[i].iv, tests[i].aad, tests[i].aadlen, plaintext); sz2 = psChacha20Poly1305IetfDecryptDetached( &dCtx, ciphertext, tests[i].ptlen, tests[i].iv, tests[i].aad, tests[i].aadlen, tests[i].tag, plaintext2); if (sz1 != tests[i].ptlen) { Printf("FAILED: authentication failed (psChacha20Poly1305IetfDecrypt)\n"); } else if (Memcmp(plaintext, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: data mismatch (psChacha20Poly1305IetfDecryptDetached)\n"); } else if (sz2 != (psResSize_t) tests[i].ptlen) { Printf("FAILED: authentication failed (psChacha20Poly1305IetfDecryptDetached)\n"); } else if (Memcmp(plaintext2, tests[i].pt, tests[i].ptlen) != 0) { Printf("FAILED: data mismatch (psChacha20Poly1305IetfDecryptDetached)\n"); } else { Printf("PASSED\n"); } psFree(cipherTextAuthData, NULL); psChacha20Poly1305IetfClear(&dCtx); } return PS_SUCCESS; } #endif /* USE_CHACHA20_POLY1305_IETF */ /******************************************************************************/ #ifdef USE_DES # define DES_ITER 1000 static int32 psDesTest(void) { int32 err; static const struct des_test_case { int32 num, mode; /* mode 1 = encrypt */ unsigned char key[8], txt[8], out[8]; } cases[] = { { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, { 10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } } }; int32 i, y; unsigned char tmp[8]; psDes3Key_t des; for (i = 0; i < (int) (sizeof(cases) / sizeof(cases[0])); i++) { if ((err = psDesInitKey(cases[i].key, 8, &des)) != PS_SUCCESS) { return err; } if (cases[i].mode != 0) { _psTraceInt(" DES known vector encrypt test %d... ", cases[i].num); psDesEncryptBlock(cases[i].txt, tmp, &des); } else { _psTraceInt(" DES known vector encrypt test %d... ", cases[i].num); psDesDecryptBlock(cases[i].txt, tmp, &des); } if (Memcmp(cases[i].out, tmp, sizeof(tmp)) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } else { _psTrace("PASSED\n"); } /* now see if we can encrypt all zero bytes DES_ITER times, decrypt and come back where we started */ _psTrace(" DES wind/unwind test... "); for (y = 0; y < 8; y++) { tmp[y] = 0; } for (y = 0; y < DES_ITER; y++) { psDesEncryptBlock(tmp, tmp, &des); } for (y = 0; y < DES_ITER; y++) { psDesDecryptBlock(tmp, tmp, &des); } for (y = 0; y < 8; y++) { if (tmp[y] != 0) { _psTrace("FAILED: memcmp\n"); return -1; } } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* DES */ #if defined(USE_PKCS5) && defined(USE_HMAC_SHA1) int32 psPBKDF2(void) { int32 i; unsigned char key[32]; static struct { int32 rounds, dkLen; unsigned char *pass, *salt; unsigned char output[32]; } tests[] = { { 1, 20, (unsigned char *) "password", (unsigned char *) "salt", { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6 } }, { 4096, 20, (unsigned char *) "password", (unsigned char *) "salt", { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, 0x65, 0xa4, 0x29, 0xc1 } }, { 4096, 25, (unsigned char *) "passwordPASSWORDpassword", (unsigned char *) "saltSALTsaltSALTsaltSALTsaltSALTsalt", { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, 0x38 } } }; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" PBKDF2 known vector test %d... ", i + 1); psPkcs5Pbkdf2(tests[i].pass, (uint32) Strlen((char *) tests[i].pass), tests[i].salt, (uint32) Strlen((char *) tests[i].salt), tests[i].rounds, key, tests[i].dkLen); if (Memcmp(key, tests[i].output, tests[i].dkLen) != 0) { _psTrace("FAILED\n"); } else { _psTrace("PASSED\n"); } } return 0; } #endif /* PKCS5 */ /******************************************************************************/ #ifdef USE_3DES int32 psDes3Test(void) { static struct { unsigned char key[24], iv[8], pt[8], ct[8]; } tests[] = { { { 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x95, 0xa8, 0xd7, 0x28, 0x13, 0xda, 0xa9, 0x4d } }, { { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { { 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31, 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31, 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x88, 0xd5, 0x5e, 0x54, 0xf5, 0x4c, 0x97, 0xb4 } } }; psDes3_t skey; unsigned char ct[32]; int32 i; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" 3DES CBC known vector test %d... ", i + 1); if (psDes3Init(&skey, tests[i].iv, tests[i].key) < 0) { return PS_FAILURE; } psDes3Encrypt(&skey, tests[i].pt, ct, DES3_BLOCKLEN); if (Memcmp(ct, tests[i].ct, DES3_BLOCKLEN) != 0) { _psTrace("FAILED\n"); } else { _psTrace("PASSED\n"); } psDes3Clear(&skey); } return 0; } #endif /* USE_3DES */ /******************************************************************************/ #ifdef USE_ARC4 int32 psArc4Test(void) { static struct { int32 keylen, ptlen; unsigned char key[24], pt[16], ct[16]; } tests[] = { { 5, 16, { 0x01, 0x02, 0x03, 0x04, 0x05 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27, 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8 } }, { 8, 8, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96} } }; psArc4_t skey; unsigned char ct[32]; int32 i; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" RC4 known vector test %d... ", i + 1); if (psArc4Init(&skey, tests[i].key, tests[i].keylen) < 0) { return PS_FAILURE; } psArc4(&skey, tests[i].pt, ct, tests[i].ptlen); if (Memcmp(ct, tests[i].ct, tests[i].ptlen) != 0) { _psTrace("FAILED\n"); } else { _psTrace("PASSED\n"); } psArc4Clear(&skey); } return 0; } #endif /* USE_ARC4 */ #ifdef USE_IDEA int32 psIdeaTest(void) { int32 err, i; psIdea_t eCtx, dCtx; unsigned char tmp[2][IDEA_BLOCKLEN]; static struct { unsigned char key[IDEA_KEYLEN], iv[IDEA_IVLEN], pt[16], ct[16]; } tests[] = { { { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, { 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x21, 0x21, 0x21, 0x0a }, { 0x57, 0x1c, 0xce, 0x5a, 0xea, 0xee, 0x81, 0x04, 0x87, 0x2a, 0x5a, 0xa9, 0xe2, 0xdf, 0x64, 0xa9 } } }; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTrace(" IDEA-CBC known vector test 1... "); if ((err = psIdeaInit(&eCtx, tests[i].iv, tests[i].key)) != PS_SUCCESS) { _psTraceInt("FAILED: psIdeaInit returned %d\n", err); return err; } if ((err = psIdeaInit(&dCtx, tests[i].iv, tests[i].key)) != PS_SUCCESS) { _psTraceInt("FAILED: psIdeaInit returned %d\n", err); return err; } psIdeaEncrypt(&eCtx, tests[i].pt, tmp[0], 16); /* psTraceBytes("IDEA CT", tmp[0], 16); */ if (Memcmp(tmp[0], tests[i].ct, 16) != 0) { _psTrace("FAILED\n"); } else { _psTrace("PASSED\n"); } _psTrace(" IDEA-CBC known vector test 2... "); psIdeaDecrypt(&dCtx, tmp[0], tmp[1], 16); /* psTraceBytes("IDEA PT", tmp[1], 16); */ if (Memcmp(tmp[1], tests[i].pt, 16) != 0) { _psTrace("FAILED\n"); } else { _psTrace("PASSED\n"); } psIdeaClear(&eCtx); psIdeaClear(&dCtx); } return 0; } #endif /******************************************************************************/ #ifdef USE_SEED /* Performs a self-test of the SEED block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int32 psSeedTest(void) { # if 0 static const struct test { unsigned char pt[16], ct[16], key[16]; } tests[] = { { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x5E, 0xBA, 0xC6, 0xE0, 0x05, 0x4E, 0x16, 0x68, 0x19, 0xAF, 0xF1, 0xCC, 0x6D, 0x34, 0x6C, 0xDB }, { 0 }, }, { { 0 }, { 0xC1, 0x1F, 0x22, 0xF2, 0x01, 0x40, 0x50, 0x50, 0x84, 0x48, 0x35, 0x97, 0xE4, 0x37, 0x0F, 0x43 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, }, { { 0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9, 0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D }, { 0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D, 0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A }, { 0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8, 0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85 }, }, { { 0xB4, 0x1E, 0x6B, 0xE2, 0xEB, 0xA8, 0x4A, 0x14, 0x8E, 0x2E, 0xED, 0x84, 0x59, 0x3C, 0x5E, 0xC7 }, { 0x9B, 0x9B, 0x7B, 0xFC, 0xD1, 0x81, 0x3C, 0xB9, 0x5D, 0x0B, 0x36, 0x18, 0xF4, 0x0F, 0x51, 0x22 }, { 0x28, 0xDB, 0xC3, 0xBC, 0x49, 0xFF, 0xD8, 0x7D, 0xCF, 0xA5, 0x09, 0xB1, 0x1D, 0x42, 0x2B, 0xE7 }, } }; int32 x; unsigned char buf[2][16]; psSeedKey_t skey; for (x = 0; x < (int) (sizeof(tests) / sizeof(tests[0])); x++) { psSeedInitKey(tests[x].key, 16, &skey); psSeedEncryptBlock(tests[x].pt, buf[0], &skey); psSeedDecryptBlock(buf[0], buf[1], &skey); if (Memcmp(buf[0], tests[x].ct, 16) || Memcmp(buf[1], tests[x].pt, 16)) { _psTraceInt("SEED failure: test %d failed\n", x); return -1; } psSeedClear(&skey); } # endif _psTrace(" SEED unimplemented\n"); return PS_SUCCESS; } #endif /* USE_SEED */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_SHA1 int32 psSha1Test(void) { static const struct { char *msg; unsigned char hash[SHA1_HASHLEN]; } tests[] = { { "abc", { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } }, { "The quick brown fox jumps over the lazy dog", { 0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc,0xed, 0x84, 0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12 } }, { "adfkadsofijadlkjoaijeoadaoijealfkajeflakepoieuproeirupqoeiruadslfasdlfadfowifjadfaleifafoeafwdflaheadfalefaahfaefefaeofadflafefaefeaeorea", { 0xb5, 0x6a, 0x92, 0x83, 0x2a, 0xb8, 0x98, 0xdf,0x37, 0xf6, 0x4b, 0x5b, 0x95, 0x9b, 0xfe, 0x9a, 0xb5, 0x9f, 0x36, 0x86 } } }; int32 i; unsigned char tmp[SHA1_HASHLEN]; psSha1_t md; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" SHA-1 known vector test %d... ", i + 1); psSha1PreInit(&md); psSha1Init(&md); psSha1Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); psSha1Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, SHA1_HASHLEN) != 0) { _psTrace("FAILED: mem compare failure\n"); return -1; } else { _psTrace("PASSED\n"); } } return PS_SUCCESS; } #endif /* USE_SHA1 */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_SHA256 int32 psSha256Test2(void) { unsigned char hash[32]; const unsigned char expect[32] = { 0x1, 0xd, 0x0, 0xed, 0xa0, 0x5, 0xa3, 0x8c, 0xcb, 0x98, 0xc3, 0x9b, 0x2d, 0xb1, 0x43, 0x2d, 0x59, 0x9, 0x8, 0x37, 0x40, 0x31, 0x5e, 0x9b, 0x27, 0xec, 0x92, 0xf7, 0x2, 0xa7, 0x1c, 0x18 }; const unsigned char expect2[32] = { 0x5a, 0x31, 0xd2, 0xdf, 0x29, 0x5c, 0x83, 0x76, 0x92, 0x64, 0xae, 0x53, 0xcd, 0xc8, 0xeb, 0x56, 0xfc, 0x55, 0x3, 0x6, 0x92, 0xe, 0x8b, 0xab, 0x18, 0x7b, 0x47, 0xd1, 0xa2, 0x96, 0x31, 0xe }; const unsigned char expect3[32] = { 0xff, 0x16, 0x42, 0xc4, 0x77, 0x1, 0x1d, 0x25, 0xd, 0x48, 0xe4, 0x2d, 0xba, 0xab, 0x4f, 0x14, 0x1e, 0xd5, 0x7f, 0xd6, 0x60, 0x9e, 0x51, 0x91, 0xab, 0x4, 0xf9, 0xf6, 0xf6, 0x5d, 0x8f, 0x22 }; unsigned char array[65536]; unsigned char array2[65536]; unsigned char array3[65536]; psSha256_t md; psSha256_t md2; psSha256_t md3; psSha256_t md4; int i; int blocksize; int blocksize2; int blocksize3; /* This test assumes there is 1 or 2 simultanous digest contexts in underlying implementation of cryptography, as is the case with some non-default crypto implementations. The test works with more than that, but may not check of the implementation. */ /* Additional tests, using multiple simultaneous contexts, and large data. */ /* First perform hashes with single blocks and serially. */ for (i = 0; i < sizeof(array); i++) { array[i] = 7 + (i * 2048) % 127; array2[i] = 17 + (i * 4096) % 197; array3[i] = 21 + (i * 8192) % 227; } Memset(hash, 0, sizeof(hash)); psSha256PreInit(&md); /* Pre-init before first use. */ psSha256Init(&md); psSha256Update(&md, array, 65536); psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { Abort(); _psTrace("FAILED: memcmp\n"); return -1; } memset(hash, 0, sizeof(hash)); psSha256Standalone(array, 65536, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: psSha256Standalone KAT mismatch.\n"); Abort(); return -1; } Memset(hash, 0, sizeof(hash)); psSha256PreInit(&md2); /* Pre-init before first use. */ psSha256Init(&md2); psSha256Update(&md2, array2, 65536); psSha256Final(&md2, hash); if (Memcmp(hash, expect2, 32) != 0) { Abort(); _psTrace("FAILED: memcmp\n"); return -1; } Memset(hash, 0, sizeof(hash)); psSha256PreInit(&md3); /* Pre-init before first use. */ psSha256Init(&md3); psSha256Update(&md3, array3, 65536); psSha256Final(&md3, hash); if (Memcmp(hash, expect3, 32) != 0) { Abort(); _psTrace("FAILED: memcmp\n"); return -1; } /* Then perform hashes with two blocks and serially, using same context. */ Memset(hash, 0, sizeof(hash)); psSha256Init(&md); psSha256Update(&md, array, 32768); psSha256Update(&md, array + 32768, 32768); psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: Memcmp (two part)\n"); return -1; } Memset(hash, 0, sizeof(hash)); psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Update(&md, array2 + 32768, 32768); psSha256Final(&md, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (two part)\n"); return -1; } Memset(hash, 0, sizeof(hash)); psSha256Init(&md); psSha256Update(&md, array3, 32768); psSha256Update(&md, array3 + 32768, 32768); psSha256Final(&md, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (two part)\n"); return -1; } /* Try going back within the same context: First initialize and update and then initialize and update again. */ Memset(hash, 0, sizeof(hash)); psSha256Init(&md); psSha256Update(&md, array, 32768); psSha256Init(&md); psSha256Update(&md, array3, 32768); psSha256Update(&md, array3 + 32768, 32768); psSha256Final(&md, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (two part)\n"); return -1; } /* Do operations in parallel with three md contexts, single block. */ psSha256Init(&md); psSha256Init(&md2); psSha256Init(&md3); psSha256Update(&md, array, 65536); psSha256Update(&md2, array2, 65536); psSha256Update(&md3, array3, 65536); psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md2, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md3, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Do operations in parallel with three md contexts, multiple blocks. */ blocksize = 256; psSha256Init(&md); psSha256Init(&md2); psSha256Init(&md3); for (i = 0; i < 65536; i += blocksize) { psSha256Update(&md, &array[i], blocksize); psSha256Update(&md2, &array2[i], blocksize); psSha256Update(&md3, &array3[i], blocksize); } psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md2, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md3, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Do operations in parallel with three md contexts, multiple blocks. Different block sizes for different md contexts. */ blocksize = 256; blocksize2 = 512; blocksize3 = 2048; psSha256Init(&md); psSha256Init(&md2); psSha256Init(&md3); for (i = 0; i < 65536; i += blocksize) { psSha256Update(&md, &array[i], blocksize); if ((i % blocksize2) != 0) { continue; } psSha256Update(&md2, &array2[i], blocksize2); if ((i % blocksize3) != 0) { continue; } psSha256Update(&md3, &array3[i], blocksize3); } psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md2, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } psSha256Final(&md3, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Multipart with context transfer (using memory copy). */ psSha256Init(&md); psSha256Update(&md, array3, 32768); psSha256Sync(&md, 0); /* Need to synchronize before it is allowed to copy, zeroize or free md memory. */ Memcpy(&md3, &md, sizeof(md3)); psSha256Update(&md3, array3 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect3, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Multipart with context transfer (using state copying). */ psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Sync(&md, 0); /* Need to synchronize before it is allowed to copy, zeroize or free md memory. */ Memcpy(&md3, &md, sizeof(md3)); psSha256Update(&md3, array2 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Multipart with context transfer (using state copying and memcpy). */ psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Cpy(&md3, &md); psSha256Sync(&md3, 0); psSha256Sync(&md, 0); /* Need to synchronize before it is allowed to copy, zeroize or free md memory. */ Memcpy(&md3, &md, sizeof(md3)); psSha256Update(&md3, array2 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (single part; parallel contexts)\n"); return -1; } /* Multipart with context transfer (using state copying), when state is likely not loaded (variants with different amount of activity in between Update and Cpy. */ psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Init(&md2); psSha256Update(&md2, array, 32768); psSha256Update(&md2, array, 32768); psSha256Final(&md2, hash); psSha256Cpy(&md3, &md); psSha256Update(&md3, array2 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (multi part; parallel contexts)\n"); return -1; } psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Init(&md2); psSha256Update(&md2, array, 32768); psSha256Update(&md2, array, 32768); psSha256Init(&md3); psSha256Update(&md3, array, 32768); psSha256Update(&md3, array, 32768); psSha256Final(&md2, hash); psSha256Final(&md3, hash); psSha256Cpy(&md3, &md); psSha256Update(&md3, array2 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (multi part; parallel contexts)\n"); return -1; } psSha256Init(&md); psSha256Update(&md, array2, 32768); psSha256Init(&md2); psSha256Update(&md2, array, 32768); psSha256Update(&md2, array, 32768); psSha256Init(&md3); psSha256Update(&md3, array, 32768); psSha256Update(&md3, array, 32768); psSha256PreInit(&md4); psSha256Init(&md4); psSha256Update(&md4, array, 32768); psSha256Update(&md4, array, 32768); psSha256Final(&md2, hash); psSha256Final(&md3, hash); psSha256Final(&md4, hash); psSha256Cpy(&md3, &md); psSha256Update(&md3, array2 + 32768, 32768); psSha256Final(&md3, hash); if (Memcmp(hash, expect2, 32) != 0) { _psTrace("FAILED: Memcmp (multi part; parallel contexts)\n"); return -1; } /* Zeroize of context. */ psSha256Init(&md); psSha256Update(&md, array, 32768); psSha256Sync(&md, 0); /* Need to synchronize before it is allowed to copy, zeroize or free md memory. */ Memset(&md, 0, sizeof(md)); /* Note: After memset it is needed to use some other contexts. */ psSha256Init(&md2); psSha256Update(&md2, array, 32768); psSha256Update(&md2, array, 32768); psSha256Init(&md3); psSha256Update(&md3, array, 32768); psSha256Update(&md3, array, 32768); psSha256Init(&md4); psSha256Update(&md4, array, 32768); psSha256Update(&md4, array, 32768); psSha256Init(&md); psSha256Update(&md, array, 65536); psSha256Final(&md, hash); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: Memcmp (memset in between)\n"); return -1; } psSha256Final(&md2, hash); psSha256Final(&md3, hash); psSha256Final(&md4, hash); /* Sync is ok for zeroized memory not used as context and initialized or finalized context. */ Memset(&md, 0, sizeof(md)); psSha256Sync(&md, 0); Memset(&md, 0, sizeof(md)); psSha256Init(&md); psSha256Sync(&md, 0); psSha256Init(&md); psSha256Update(&md, array, 65536); psSha256Final(&md, hash); psSha256Sync(&md, 0); if (Memcmp(hash, expect, 32) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } return PS_SUCCESS; } int32 psSha256Test(void) { static const struct { char *msg; char *moreMsg; unsigned char hash[SHA256_HASHLEN]; } tests[] = { { "abc", NULL, { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } }, { "ab", "c", { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL, { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } }, { "abcdbcdecd", "efdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } }, { "The quick brown fox jumps over the lazy dog", NULL, { 0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94, 0x69, 0xca, 0x9a, 0xbc, 0xb0, 0x08, 0x2e, 0x4f, 0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76, 0x2d, 0x02, 0xd0, 0xbf, 0x37, 0xc9, 0xe5, 0x92 } }, { "The quick brow", "n fox jumps over the lazy dog", { 0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94, 0x69, 0xca, 0x9a, 0xbc, 0xb0, 0x08, 0x2e, 0x4f, 0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76, 0x2d, 0x02, 0xd0, 0xbf, 0x37, 0xc9, 0xe5, 0x92 } }, { "adfkadsofijadlkjoaijeoadaoijealfkajeflakepoieuproeirupqoeiruadslfasdlfadfowifjadfaleifafoeafwdflaheadfalefaahfaefefaeofadflafefaefeaeorea", NULL, { 0xd9, 0xe0, 0xb1, 0xfb, 0x08, 0x8a, 0xe4, 0xb9, 0xfe, 0xf0, 0xb2, 0xb8, 0x33, 0x9e, 0x0f, 0xea, 0x59, 0xa7, 0x35, 0x7f, 0x5b, 0x65, 0xde, 0x42, 0x7b, 0xaa, 0x28, 0x89, 0xfd, 0x5f, 0x49, 0xd0 } }, { "adfkadsofijadlkjoaijeoadaoijealfkajeflakepoieuproeirupqoeiruadslfasdlfadfowifjadfaleifafoeafwdflaheadfalefaahfaefef", "aeofadflafefaefeaeorea", { 0xd9, 0xe0, 0xb1, 0xfb, 0x08, 0x8a, 0xe4, 0xb9, 0xfe, 0xf0, 0xb2, 0xb8, 0x33, 0x9e, 0x0f, 0xea, 0x59, 0xa7, 0x35, 0x7f, 0x5b, 0x65, 0xde, 0x42, 0x7b, 0xaa, 0x28, 0x89, 0xfd, 0x5f, 0x49, 0xd0 } } }; int32 i; unsigned char tmp[SHA256_HASHLEN]; psSha256_t md; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" SHA-256 known vector test %d... ", i + 1); psSha256PreInit(&md); psSha256Init(&md); psSha256Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); if (tests[i].moreMsg != NULL) { psSha256Update(&md, (unsigned char *) tests[i].moreMsg, (uint32) Strlen(tests[i].moreMsg)); } psSha256Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, SHA256_HASHLEN) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } else { _psTrace("PASSED\n"); } } _psTrace(" SHA-256 robustness test... "); if (psSha256Test2() == PS_SUCCESS) { _psTrace("PASSED\n"); } else { return -1; } return PS_SUCCESS; } #endif /* USE_SHA256 */ /******************************************************************************/ #ifdef USE_SHA224 /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int32 psSha224Test(void) { static const struct { char *msg; unsigned char hash[28]; } tests[] = { { "abc", { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } }, }; int i; unsigned char tmp[28]; psSha256_t md; for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" SHA-224 known vector test %d... ", i + 1); psSha224Init(&md); psSha224Update(&md, (unsigned char *) tests[i].msg, (unsigned long) Strlen(tests[i].msg)); psSha224Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, 28) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } else { _psTrace("PASSED\n"); } } return PS_SUCCESS; } #endif /* USE_SHA224 */ /******************************************************************************/ #ifdef USE_SHA512 int32 psSha512Test(void) { static const struct { char *msg; unsigned char hash[SHA512_HASHLEN]; } tests[] = { { "abc", { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } }, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } }, }; int i; unsigned char tmp[SHA512_HASHLEN]; psSha512_t md; for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" SHA-512 known vector test %d... ", i + 1); psSha512PreInit(&md); psSha512Init(&md); psSha512Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); psSha512Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, SHA512_HASHLEN) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* USE_SHA512 */ #ifdef USE_SHA384 int32 psSha384Test(void) { static const struct { char *msg; unsigned char hash[SHA384_HASHLEN]; } tests[] = { { "abc", { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } }, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } }, }; int i; unsigned char tmp[SHA384_HASHLEN]; psSha384_t md; for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" SHA-384 known vector test %d... ", i + 1); psSha384PreInit(&md); psSha384Init(&md); psSha384Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); psSha384Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, SHA384_HASHLEN) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* USE_SHA384 */ #ifdef USE_MD5SHA1 int32 psMd5Sha1Test(void) { static const struct { char *msg; unsigned char hash[36]; } tests[] = { { "abc", { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72, 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x82, 0x15, 0xef, 0x07, 0x96, 0xa2, 0x0b, 0xca, 0xaa, 0xe1, 0x16, 0xd3, 0x87, 0x6c, 0x66, 0x4a, 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } }, { "The quick brown fox jumps over the lazy dog", { 0x9e, 0x10, 0x7d, 0x9d, 0x37, 0x2b, 0xb6, 0x82, 0x6b, 0xd8, 0x1d, 0x35, 0x42, 0xa4, 0x19, 0xd6, 0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, 0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12 } }, { "adfkadsofijadlkjoaijeoadaoijealfkajeflakepoieuproeirupqoeiruadslfasdlfadfowifjadfaleifafoeafwdflaheadfalefaahfaefefaeofadflafefaefeaeorea", { 0x1b, 0x92, 0x8a, 0x64, 0x43, 0xfd, 0xdf, 0xa2, 0x17, 0x05, 0x3b, 0x25, 0x08, 0x20, 0x81, 0xe5, 0xb5, 0x6a, 0x92, 0x83, 0x2a, 0xb8, 0x98, 0xdf, 0x37, 0xf6, 0x4b, 0x5b, 0x95, 0x9b, 0xfe, 0x9a, 0xb5, 0x9f, 0x36, 0x86 } }, }; int32 i; unsigned char tmp[36]; psMd5Sha1_t md; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" MD5SHA1 known vector test %d... ", i + 1); psMd5Sha1PreInit(&md); psMd5Sha1Init(&md); psMd5Sha1Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); psMd5Sha1Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, 36) != 0) { _psTrace("FAILED: mem compare failure\n"); return -1; } else { _psTrace("PASSED\n"); } } return PS_SUCCESS; } #endif /* USE_MD5SHA1 */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_MD5 int32 psMd5Test(void) { static const struct { char *msg; unsigned char hash[16]; } tests[] = { { "", { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, { "a", { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, { "abc", { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, { "message digest", { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, { "abcdefghijklmnopqrstuvwxyz", { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, { NULL, { 0 } } }; int32 i; unsigned char tmp[MD5_HASHLEN]; psMd5_t md; for (i = 0; tests[i].msg != NULL; i++) { _psTraceInt(" MD5 known vector test %d... ", i + 1); psMd5PreInit(&md); if (psMd5Init(&md) < 0) { _psTrace("FAILED: psMd5Init\n"); return -1; } psMd5Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)); psMd5Final(&md, tmp); if (Memcmp(tmp, tests[i].hash, MD5_HASHLEN) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* USE_MD5 */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_MD4 int32 psMd4Test(void) { static const struct md4_test_case { char *input; unsigned char digest[16]; } cases[] = { { "", { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 } }, { "a", { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 } }, { "abc", { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d } }, { "message digest", { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b } }, { "abcdefghijklmnopqrstuvwxyz", { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 } }, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 } }, }; int32 i; psMd4_t md; unsigned char digest[16]; for (i = 0; i < (int32) (sizeof(cases) / sizeof(cases[0])); i++) { _psTraceInt(" MD4 known vector test %d... ", i + 1); psMd4Init(&md); psMd4Update(&md, (unsigned char *) cases[i].input, (uint32) Strlen(cases[i].input)); psMd4Final(&md, digest); if (Memcmp(digest, cases[i].digest, 16) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* USE_MD4 */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_MD2 int32 psMd2Test(void) { static const struct { char *msg; unsigned char md[16]; } tests[] = { { "", { 0x83, 0x50, 0xe5, 0xa3, 0xe2, 0x4c, 0x15, 0x3d, 0xf2, 0x27, 0x5c, 0x9f, 0x80, 0x69, 0x27, 0x73 } }, { "a", { 0x32, 0xec, 0x01, 0xec, 0x4a, 0x6d, 0xac, 0x72, 0xc0, 0xab, 0x96, 0xfb, 0x34, 0xc0, 0xb5, 0xd1 } }, { "message digest", { 0xab, 0x4f, 0x49, 0x6b, 0xfb, 0x2a, 0x53, 0x0b, 0x21, 0x9f, 0xf3, 0x30, 0x31, 0xfe, 0x06, 0xb0 } }, { "abcdefghijklmnopqrstuvwxyz", { 0x4e, 0x8d, 0xdf, 0xf3, 0x65, 0x02, 0x92, 0xab, 0x5a, 0x41, 0x08, 0xc3, 0xaa, 0x47, 0x94, 0x0b } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0xda, 0x33, 0xde, 0xf2, 0xa4, 0x2d, 0xf1, 0x39, 0x75, 0x35, 0x28, 0x46, 0xc3, 0x03, 0x38, 0xcd } }, { "1234567890123456789012345678901234567890" "1234567890123456789012345678901234567890", { 0xd5, 0x97, 0x6f, 0x79, 0xd8, 0x3d, 0x3a, 0x0d, 0xc9, 0x80, 0x6c, 0x3c, 0x66, 0xf3, 0xef, 0xd8 } } }; int32 i; psMd2_t md; unsigned char buf[16]; for (i = 0; i < (int32) (sizeof(tests) / sizeof(tests[0])); i++) { _psTraceInt(" MD2 known vector test %d... ", i + 1); psMd2PreInit(&md); psMd2Init(&md); if (psMd2Update(&md, (unsigned char *) tests[i].msg, (uint32) Strlen(tests[i].msg)) < 0) { _psTrace("FAILED: psMd2Update\n"); return -1; } if (psMd2Final(&md, buf) < 0) { _psTrace("FAILED: psMd2Final\n"); return -1; } if (Memcmp(buf, tests[i].md, 16) != 0) { _psTrace("FAILED: memcmp\n"); return -1; } _psTrace("PASSED\n"); } return PS_SUCCESS; } #endif /* USE_MD2 */ /******************************************************************************/ /******************************************************************************/ #ifdef USE_RSA # ifdef USE_PRIVATE_KEY_PARSING typedef void pkaCmdInfo_t; /* Sample keys and certs in memory for RSA testing */ # include "../../testkeys/RSA/1024_RSA.h" # include "../../testkeys/RSA/1024_RSA_KEY.h" # include "../../testkeys/RSA/2048_RSA.h" # include "../../testkeys/RSA/2048_RSA_KEY.h" # include "../../testkeys/RSA/3072_RSA.h" # include "../../testkeys/RSA/3072_RSA_KEY.h" # include "../../testkeys/RSA/4096_RSA.h" # include "../../testkeys/RSA/4096_RSA_KEY.h" # include "../../testkeys/RSA/2048_RSA_PUB_pem.h" struct { psSize_t size; /* Size of public key exponent in bytes */ const unsigned char *key; /* PKCS#1 key string */ const unsigned char *cert; /* X.509 cert string */ psSize_t keysize; /* Length of PKCS#1 key string */ psSize_t certsize; /* Length of X.509 cert string */ } rsa[3] = { { 128, RSA1024KEY, RSA1024, sizeof(RSA1024KEY), sizeof(RSA1024) }, { 256, RSA2048KEY, RSA2048, sizeof(RSA2048KEY), sizeof(RSA2048) }, { 512, RSA4096KEY, RSA4096, sizeof(RSA4096KEY), sizeof(RSA4096) } }; static unsigned char RSA2048KEY_E3[] = { 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb5, 0x7e, 0x18, 0xf8, 0x8e, 0xaa, 0xa2, 0x6f, 0x3a, 0xb4, 0xeb, 0xe8, 0xa4, 0xd3, 0x10, 0xa0, 0x60, 0x85, 0xc7, 0x7d, 0xe6, 0x4b, 0x75, 0x1d, 0x71, 0x12, 0x6a, 0xeb, 0x3d, 0x43, 0x74, 0x86, 0xb9, 0xa8, 0x50, 0x61, 0x9c, 0xa0, 0x3d, 0xeb, 0x56, 0x5e, 0xb2, 0xbc, 0xd2, 0x95, 0xd4, 0x5e, 0xd7, 0x18, 0x50, 0xa3, 0x5b, 0xc0, 0x92, 0x9d, 0xa0, 0x03, 0xac, 0x73, 0x62, 0xe9, 0x50, 0x47, 0x9c, 0xa8, 0x69, 0x7a, 0xe0, 0xb9, 0x1e, 0x36, 0x71, 0x8d, 0x05, 0x3c, 0x77, 0x12, 0x7a, 0x30, 0xab, 0x8f, 0x03, 0x5e, 0xb7, 0xea, 0x90, 0x55, 0xf8, 0xa1, 0x2f, 0xb3, 0x97, 0x33, 0xf2, 0x80, 0x30, 0x75, 0x4c, 0x90, 0x4f, 0x94, 0x04, 0x2a, 0x88, 0xfa, 0xcd, 0x00, 0x0b, 0x52, 0x50, 0x22, 0x04, 0x76, 0x88, 0xc5, 0xc4, 0x81, 0xf2, 0x19, 0x26, 0x0d, 0xb6, 0xfe, 0x96, 0x5e, 0x4b, 0x36, 0x67, 0x79, 0x3a, 0x11, 0x78, 0x64, 0xa5, 0xbb, 0xf4, 0xc4, 0x9f, 0x8a, 0xef, 0xa2, 0x3e, 0x23, 0x67, 0x46, 0xd9, 0x47, 0xd3, 0xcf, 0x5b, 0x9a, 0x9b, 0x38, 0xe9, 0x8c, 0xf2, 0xa2, 0x08, 0x6c, 0xbf, 0xfa, 0x01, 0x24, 0x97, 0xf4, 0x3a, 0x96, 0x9c, 0xd7, 0x56, 0xba, 0x3a, 0xa4, 0x4e, 0x18, 0x53, 0xa7, 0x7a, 0xe2, 0x11, 0x58, 0x9e, 0xa4, 0x05, 0xba, 0xf9, 0x2a, 0x20, 0x68, 0xb7, 0x25, 0x0b, 0xbe, 0xad, 0xb7, 0x97, 0x98, 0x87, 0xb9, 0xae, 0x46, 0x0d, 0x5a, 0x80, 0x01, 0xf8, 0x60, 0xca, 0x41, 0x9a, 0x00, 0x2f, 0x21, 0x0d, 0x14, 0x70, 0x73, 0xb9, 0xb0, 0x98, 0x70, 0x76, 0x4f, 0x23, 0x4f, 0x3c, 0x8c, 0x05, 0x34, 0xd6, 0x04, 0x7e, 0x01, 0x6b, 0x64, 0x90, 0xea, 0xe4, 0x3c, 0xbe, 0x0d, 0xa4, 0xed, 0x2e, 0xe9, 0xd4, 0x7b, 0x8a, 0xe1, 0xc5, 0x06, 0x6b, 0x8c, 0xa6, 0x53, 0x02, 0x01, 0x03, 0x02, 0x82, 0x01, 0x00, 0x78, 0xfe, 0xbb, 0x50, 0x5f, 0x1c, 0x6c, 0x4a, 0x27, 0x23, 0x47, 0xf0, 0x6d, 0xe2, 0x0b, 0x15, 0x95, 0xae, 0x84, 0xfe, 0x99, 0x87, 0xa3, 0x68, 0xf6, 0x0c, 0x47, 0x47, 0x7e, 0x2c, 0xf8, 0x59, 0xd1, 0x1a, 0xe0, 0x41, 0x13, 0x15, 0x7e, 0x9c, 0xe4, 0x3f, 0x21, 0xd3, 0x37, 0x0e, 0x8d, 0x94, 0x8f, 0x65, 0x8b, 0x17, 0x92, 0x80, 0x61, 0xbe, 0x6a, 0xad, 0x1d, 0xa2, 0x41, 0xf0, 0xe0, 0x2f, 0xbd, 0xc5, 0x9b, 0xa7, 0x40, 0x7b, 0x69, 0x79, 0xa1, 0x08, 0xae, 0x28, 0x4f, 0x61, 0xa6, 0xcb, 0x1d, 0x0a, 0x02, 0x3f, 0x25, 0x47, 0x0a, 0xe3, 0xfb, 0x16, 0x1f, 0xcd, 0x0f, 0x77, 0xf7, 0x00, 0x20, 0x4e, 0x33, 0x0a, 0xdf, 0xb8, 0x02, 0xc7, 0x05, 0xfc, 0x88, 0xaa, 0xb2, 0x36, 0xe0, 0x16, 0xad, 0xa4, 0x5b, 0x2e, 0x83, 0x01, 0x4c, 0x10, 0xc4, 0x09, 0x24, 0xa9, 0xb9, 0x94, 0x32, 0x23, 0x25, 0x8f, 0x56, 0x3d, 0x0e, 0xcf, 0xa3, 0x60, 0xfd, 0x19, 0xca, 0x22, 0x4e, 0x8b, 0xe1, 0x02, 0x4e, 0x7b, 0xd4, 0xb7, 0x0a, 0x67, 0x3d, 0x64, 0x85, 0x08, 0x45, 0x52, 0x0f, 0x50, 0x3b, 0x15, 0x8d, 0x87, 0x4d, 0x95, 0x7d, 0xb9, 0xb1, 0x10, 0x99, 0x21, 0xef, 0x23, 0xca, 0xfd, 0x2a, 0x94, 0xbe, 0x8a, 0xca, 0xa2, 0x0d, 0x32, 0x00, 0xc0, 0xf2, 0x47, 0x13, 0xa4, 0x83, 0xa6, 0x84, 0x12, 0xfc, 0x86, 0xfd, 0xb9, 0x3a, 0xbe, 0xbb, 0x3b, 0xc1, 0xbf, 0x88, 0x45, 0xba, 0x80, 0x5b, 0xf5, 0xdc, 0xfc, 0x57, 0x6f, 0x2d, 0xe2, 0x40, 0x41, 0xe5, 0x19, 0x71, 0xbc, 0x8d, 0xd2, 0xe3, 0x1e, 0x1e, 0x21, 0x5e, 0x0b, 0x50, 0xe8, 0xfd, 0x43, 0x62, 0xc2, 0x7d, 0xe9, 0xd1, 0x9d, 0xbc, 0x87, 0xfc, 0x74, 0xfc, 0xcf, 0xb3, 0x1d, 0xd5, 0x70, 0xcc, 0x04, 0x73, 0x25, 0xed, 0x40, 0x37, 0x2b, 0x02, 0x81, 0x81, 0x00, 0xda, 0x34, 0xb4, 0x0e, 0x0e, 0x9a, 0xf1, 0xba, 0xda, 0xe5, 0x4f, 0x70, 0xdf, 0x5c, 0xe3, 0x80, 0xb1, 0xcc, 0x85, 0xb8, 0x6c, 0xb2, 0x92, 0xbb, 0x5d, 0x63, 0x57, 0x02, 0x0f, 0xb2, 0xe6, 0x05, 0x26, 0x4d, 0x84, 0x2c, 0xc0, 0x67, 0x23, 0xd6, 0xae, 0xe5, 0x02, 0x67, 0xe6, 0xcf, 0x51, 0xc5, 0x40, 0xf5, 0xa8, 0x32, 0x52, 0xe4, 0xf6, 0x23, 0x52, 0x46, 0x96, 0x58, 0x8d, 0x8b, 0x27, 0xca, 0xc9, 0x44, 0x30, 0xc8, 0x98, 0x3a, 0x65, 0x56, 0x57, 0xed, 0x7a, 0xe7, 0x93, 0xf5, 0xa2, 0xcf, 0x11, 0x41, 0x66, 0xdd, 0xdc, 0x3b, 0x3a, 0x01, 0x9a, 0xa0, 0x4c, 0x58, 0x19, 0x3d, 0x9b, 0x36, 0x99, 0x31, 0xb0, 0xc9, 0x60, 0xb5, 0x6e, 0xc0, 0x8a, 0x71, 0x00, 0xd9, 0x33, 0x1d, 0x10, 0xef, 0x15, 0xbe, 0xb9, 0x1b, 0x8c, 0x32, 0x5c, 0x09, 0x10, 0x3b, 0x0b, 0x02, 0x0f, 0xb2, 0x43, 0x33, 0x02, 0x81, 0x81, 0x00, 0xd4, 0xed, 0x84, 0xa7, 0xd3, 0x92, 0x3e, 0xef, 0x9e, 0x38, 0xa0, 0xe6, 0x9a, 0x73, 0x89, 0x1f, 0x3f, 0xc0, 0x94, 0x7c, 0xd7, 0x81, 0xec, 0xc8, 0x76, 0x49, 0x2a, 0x8f, 0xcb, 0xf6, 0xc9, 0xc7, 0x45, 0x61, 0x88, 0x97, 0x9a, 0xf6, 0x8d, 0x27, 0x08, 0x3f, 0x6d, 0x9c, 0xa3, 0x59, 0x3c, 0x73, 0xf4, 0xe1, 0xa2, 0xbc, 0xaa, 0xa8, 0xa7, 0x5f, 0x48, 0x09, 0xc5, 0x5a, 0xcd, 0x63, 0xc9, 0x3d, 0xc7, 0xb0, 0x00, 0x59, 0x27, 0x40, 0x09, 0x89, 0xb3, 0xb9, 0x46, 0x0a, 0x54, 0x4b, 0xcb, 0xa0, 0xed, 0x85, 0xaf, 0xfb, 0x8e, 0x12, 0x72, 0xaf, 0xfe, 0x2d, 0x42, 0xbd, 0xaa, 0x76, 0x86, 0x6b, 0x5c, 0xeb, 0x7e, 0xb1, 0xab, 0x21, 0xeb, 0x5e, 0xdf, 0x6c, 0xad, 0xac, 0xa3, 0x61, 0x38, 0x81, 0xad, 0x9f, 0x70, 0x9a, 0x16, 0x0a, 0xb8, 0x49, 0x48, 0xa0, 0x0d, 0x4b, 0x77, 0xfa, 0x10, 0x61, 0x02, 0x81, 0x81, 0x00, 0x91, 0x78, 0x78, 0x09, 0x5f, 0x11, 0xf6, 0x7c, 0x91, 0xee, 0x34, 0xf5, 0xea, 0x3d, 0xed, 0x00, 0x76, 0x88, 0x59, 0x25, 0x9d, 0xcc, 0x61, 0xd2, 0x3e, 0x42, 0x3a, 0x01, 0x5f, 0xcc, 0x99, 0x58, 0xc4, 0x33, 0xad, 0x73, 0x2a, 0xef, 0x6d, 0x39, 0xc9, 0xee, 0x01, 0x9a, 0x99, 0xdf, 0x8b, 0xd8, 0xd5, 0xf9, 0x1a, 0xcc, 0x37, 0x43, 0x4e, 0xc2, 0x36, 0xd9, 0xb9, 0x90, 0x5e, 0x5c, 0xc5, 0x31, 0xdb, 0x82, 0xcb, 0x30, 0x65, 0x7c, 0x43, 0x8e, 0xe5, 0x48, 0xfc, 0x9a, 0x62, 0xa3, 0xc1, 0xdf, 0x60, 0xd6, 0x44, 0x93, 0xe8, 0x27, 0x7c, 0x01, 0x11, 0xc0, 0x32, 0xe5, 0x66, 0x29, 0x12, 0x24, 0x66, 0x21, 0x20, 0x86, 0x40, 0x78, 0xf4, 0x80, 0x5c, 0x4b, 0x55, 0xe6, 0x22, 0x13, 0x60, 0x9f, 0x63, 0xd4, 0x7b, 0x67, 0xb2, 0xcc, 0x3d, 0x5b, 0x60, 0x27, 0x5c, 0xac, 0x0a, 0x76, 0xd7, 0x77, 0x02, 0x81, 0x81, 0x00, 0x8d, 0xf3, 0xad, 0xc5, 0x37, 0xb6, 0xd4, 0x9f, 0xbe, 0xd0, 0x6b, 0x44, 0x66, 0xf7, 0xb0, 0xbf, 0x7f, 0xd5, 0xb8, 0x53, 0x3a, 0x56, 0x9d, 0xda, 0xf9, 0x86, 0x1c, 0x5f, 0xdd, 0x4f, 0x31, 0x2f, 0x83, 0x96, 0x5b, 0x0f, 0xbc, 0xa4, 0x5e, 0x1a, 0x05, 0x7f, 0x9e, 0x68, 0x6c, 0xe6, 0x28, 0x4d, 0x4d, 0xeb, 0xc1, 0xd3, 0x1c, 0x70, 0x6f, 0x94, 0xda, 0xb1, 0x2e, 0x3c, 0x88, 0xed, 0x30, 0xd3, 0xda, 0x75, 0x55, 0x90, 0xc4, 0xd5, 0x5b, 0xb1, 0x22, 0x7b, 0x84, 0x06, 0xe2, 0xdd, 0x32, 0x6b, 0x49, 0x03, 0xca, 0xa7, 0xb4, 0x0c, 0x4c, 0x75, 0x54, 0x1e, 0x2c, 0x7e, 0x71, 0xa4, 0x59, 0x9c, 0xe8, 0x9c, 0xff, 0x21, 0x1c, 0xc1, 0x47, 0x94, 0x94, 0xf3, 0x1e, 0x73, 0x17, 0x96, 0x25, 0xab, 0xc9, 0x14, 0xf5, 0xbc, 0x0e, 0xb1, 0xd0, 0x30, 0xdb, 0x15, 0x5e, 0x32, 0x4f, 0xfc, 0x0a, 0xeb, 0x02, 0x81, 0x81, 0x00, 0x87, 0xa9, 0xdc, 0x75, 0x36, 0x73, 0x1e, 0xac, 0x7d, 0xcc, 0x73, 0x64, 0x29, 0xca, 0xf3, 0x74, 0x08, 0xec, 0x25, 0x68, 0x2d, 0x9e, 0x8a, 0x78, 0x11, 0x6b, 0x0e, 0xef, 0xd1, 0xba, 0x10, 0x54, 0x06, 0xda, 0xf2, 0x41, 0xb1, 0xc2, 0xd3, 0x96, 0x70, 0x35, 0x87, 0xd9, 0x48, 0x62, 0x88, 0xd6, 0x5a, 0x86, 0xf4, 0x4d, 0x07, 0x02, 0x1b, 0xe3, 0xea, 0xc4, 0xf0, 0xb5, 0x0c, 0xa1, 0x3b, 0x2b, 0xe8, 0x7d, 0xa3, 0xe1, 0x84, 0xac, 0x0e, 0x6a, 0x19, 0xb0, 0xda, 0x05, 0xc8, 0xf5, 0x36, 0xbb, 0xec, 0x67, 0x10, 0x3a, 0xcf, 0x37, 0x31, 0x27, 0xfe, 0x34, 0x67, 0xcf, 0x3c, 0xc2, 0x69, 0xda, 0x05, 0xa0, 0xc8, 0xdd, 0x02, 0x01, 0x86, 0xa1, 0xf9, 0x05, 0xa2, 0x48, 0x82, 0x20, 0xe8, 0xbc, 0x07, 0x89, 0x82, 0x67, 0x38, 0x4d, 0x85, 0xcc, 0x43, 0x27, 0xad, 0x35, 0x8a, 0xb8, 0x11, 0x1a }; struct { psSize_t size; /* Size of public key exponent in bytes */ const unsigned char *key; /* PKCS#1 key string */ const unsigned char *cert; /* X.509 cert string */ psSize_t keysize; /* Length of PKCS#1 key string */ psSize_t certsize; /* Length of X.509 cert string */ } rsae3[1] = { { 256, RSA2048KEY_E3, NULL, sizeof(RSA2048KEY_E3), 0 } }; static int32 psRsaEncryptTest(void) { psPool_t *pool = NULL; psRsaKey_t privkey; pkaCmdInfo_t *pkaInfo; # ifdef USE_CERT_PARSE psX509Cert_t *cert; # endif /* USE_CERT_PARSE */ unsigned char out[512]; /* Large enough to hold 4096 bits of output */ unsigned char in[] = "hello"; unsigned char decrypted[6]; int i; pkaInfo = NULL; for (i = 0; i < sizeof(rsa) / sizeof(rsa[0]) && rsa[i].size >= (MIN_RSA_BITS / 8); i++) { _psTraceInt(" %d bit test...", rsa[i].size * 8); /* Start with getting both key halfs from the same source */ if (psRsaInitKey(pool, &privkey) < 0) { return -1; } #ifdef USE_PRIVATE_KEY_PARSING if (psRsaParsePkcs1PrivKey(pool, rsa[i].key, rsa[i].keysize, &privkey) < 0) { return -1; } #else _psTrace("RSA failure: private key parse not supported.\n"); return -1; #endif psRsaEncryptPub(pool, &privkey, in, sizeof(in), out, rsa[i].size, pkaInfo); psRsaDecryptPriv(pool, &privkey, out, rsa[i].size, decrypted, sizeof(decrypted), pkaInfo); if (Memcmp(decrypted, "hello", 5) != 0) { _psTrace("RSA failure: mem compare failure 1\n"); psRsaClearKey(&privkey); continue; } psRsaClearKey(&privkey); Memset(decrypted, 0x0, sizeof(decrypted)); Memset(out, 0x0, sizeof(out)); # if defined(USE_CERT_PARSE) && defined(USE_PRIVATE_KEY_PARSING) /* Get the public key from the cert */ psRsaInitKey(pool, &privkey); psRsaParsePkcs1PrivKey(pool, rsa[i].key, rsa[i].keysize, &privkey); psX509ParseCert(pool, rsa[i].cert, rsa[i].certsize, &cert, 0); psRsaEncryptPub(pool, &cert->publicKey.key.rsa, in, sizeof(in), out, rsa[i].size, pkaInfo); psRsaDecryptPriv(pool, &privkey, out, rsa[i].size, decrypted, sizeof(decrypted), pkaInfo); if (Memcmp(decrypted, "hello", 5) != 0) { psRsaClearKey(&privkey); psX509FreeCert(cert); _psTrace("RSA failure: mem compare failure 2\n"); continue; } psRsaClearKey(&privkey); psX509FreeCert(cert); Memset(decrypted, 0x0, sizeof(decrypted)); Memset(out, 0x0, sizeof(out)); # endif /* USE_CERT_PARSE */ _psTrace(" PASSED\n"); } /* key loop */ return PS_SUCCESS; } int32 psRsaSignE3Test(void) { #ifdef MIN_RSA_PUBLIC_EXPONENT #if MIN_RSA_PUBLIC_EXPONENT == 3 psPool_t *pool = NULL; unsigned char in[32] = "helloworldhelloworldhelloworld1"; unsigned char out[512]; unsigned char decrypted[32]; psRsaKey_t privkey; pkaCmdInfo_t *pkaInfo; int32_t rc; int i; pkaInfo = NULL; for (i = 0; i < sizeof(rsae3) / sizeof(rsae3[0]) && rsae3[i].size >= (MIN_RSA_BITS / 8); i++) { _psTraceInt(" %d bit test (e=3)...", rsae3[i].size * 8); psRsaInitKey(pool, &privkey); # ifdef USE_PRIVATE_KEY_PARSING psRsaParsePkcs1PrivKey(pool, rsae3[i].key, rsae3[i].keysize, &privkey); # else return -1; # endif if (psRsaEncryptPriv(pool, &privkey, in, sizeof(in), out, rsae3[i].size, pkaInfo) < 0) { psRsaClearKey(&privkey); return PS_FAILURE; } rc = psRsaDecryptPub(pool, &privkey, out, rsae3[i].size, decrypted, sizeof(decrypted), pkaInfo); if (rc < 0) { _psTraceInt(" psRsaDecryptPub failure (%d)\n", rc); psRsaClearKey(&privkey); return PS_FAILURE; } if (Memcmp(decrypted, in, sizeof(in)) != 0) { _psTraceStr("RSA failure: mem compare failure (%s)\n", (const char *) decrypted); psRsaClearKey(&privkey); return PS_FAILURE; } psRsaClearKey(&privkey); _psTrace(" PASSED\n"); } /* key loop */ #endif /* MIN_RSA_PUBLIC_EXPONENT == 3 */ #endif /* defined MIN_RSA_PUBLIC_EXPONENT */ return PS_SUCCESS; } /* Test RSA Signing, using RSA-2048 and SHA-256. */ static int32 psRsaSignTest(void) { psPool_t *pool = NULL; unsigned char in[32] = "helloworldhelloworldhelloworld1"; unsigned char out[512]; unsigned char decrypted[32]; psRsaKey_t privkey; pkaCmdInfo_t *pkaInfo; int32_t rc; int i; pkaInfo = NULL; for (i = 0; i < sizeof(rsa) / sizeof(rsa[0]) && rsa[i].size >= (MIN_RSA_BITS / 8); i++) { _psTraceInt(" %d bit test...", rsa[i].size * 8); psRsaInitKey(pool, &privkey); # ifdef USE_PRIVATE_KEY_PARSING psRsaParsePkcs1PrivKey(pool, rsa[i].key, rsa[i].keysize, &privkey); # else return -1; # endif if (psRsaEncryptPriv(pool, &privkey, in, sizeof(in), out, rsa[i].size, pkaInfo) < 0) { psRsaClearKey(&privkey); return PS_FAILURE; } rc = psRsaDecryptPub(pool, &privkey, out, rsa[i].size, decrypted, sizeof(decrypted), pkaInfo); if (rc < 0) { _psTraceInt(" psRsaDecryptPub failure (%d)\n", rc); psRsaClearKey(&privkey); return PS_FAILURE; } if (Memcmp(decrypted, in, sizeof(in)) != 0) { _psTraceStr("RSA failure: mem compare failure (%s)\n", (const char *) decrypted); psRsaClearKey(&privkey); return PS_FAILURE; } psRsaClearKey(&privkey); _psTrace(" PASSED\n"); } /* key loop */ return psRsaSignE3Test(); } # if defined(USE_RSA) && defined(USE_PEM_DECODE) static int32 psRsaKeyFormatTests(void) { unsigned char tbs[] = { 'm', 'y', 't', 'b', 's' }; psSizeL_t tbsLen = sizeof(tbs); unsigned char hashTbs[MAX_HASH_SIZE] = {0}; psSize_t hashTbsLen = sizeof(hashTbs); /* echo -n "mytbs" |openssl dgst -binary -sha256 |openssl pkeyutl -inkey testkeys/RSA/2048_RSA_KEY.pem -sign \ -pkeyopt rsa_padding_mode:pkcs1 -pkeyopt digest:sha256 |xxd -i Note: this is a PKCS #1.5 signature (used in TLS 1.2). The hash of "mytbs" is first wrapped into a DigestInfo. */ unsigned char expectedSig1[] = { 0x7f, 0x91, 0xb1, 0x24, 0xc4, 0x85, 0x12, 0x2b, 0x06, 0xef, 0xf1, 0x20, 0xbb, 0xde, 0x2b, 0x48, 0x39, 0x9b, 0x66, 0xfb, 0x1e, 0x6c, 0x8a, 0x77, 0x60, 0xec, 0x96, 0x21, 0xe3, 0x8a, 0xa0, 0xcc, 0x2f, 0x0a, 0x97, 0x6d, 0xa7, 0xd3, 0x6a, 0xb0, 0x89, 0xc2, 0x7a, 0xa4, 0x09, 0xbc, 0x87, 0xfa, 0xe3, 0x54, 0xc2, 0xde, 0xb3, 0x7d, 0x35, 0x55, 0xda, 0xb1, 0x58, 0xc2, 0x8d, 0xce, 0xfa, 0xd1, 0x5e, 0xd1, 0xd4, 0xef, 0x25, 0x22, 0x92, 0x8c, 0xdc, 0x62, 0x3a, 0xdd, 0x87, 0x8b, 0xcf, 0xfc, 0xa1, 0x6c, 0xaf, 0x83, 0xff, 0xbf, 0x29, 0x09, 0x05, 0xef, 0x76, 0x3a, 0xab, 0xba, 0xde, 0x3b, 0x16, 0xc9, 0x8e, 0x2a, 0x54, 0xe4, 0x60, 0x27, 0x57, 0xa8, 0x8c, 0xf0, 0x21, 0x05, 0xa6, 0x8e, 0x52, 0xc7, 0xe8, 0x79, 0x46, 0x46, 0x09, 0x7c, 0x75, 0xca, 0x7f, 0xc6, 0x98, 0x19, 0xcf, 0x98, 0xdf, 0x31, 0x11, 0x12, 0x66, 0x23, 0x56, 0xa6, 0xe9, 0x29, 0x71, 0xe4, 0x0f, 0x13, 0xb7, 0x1c, 0x7e, 0xeb, 0x8b, 0x22, 0xc6, 0x98, 0x64, 0xde, 0x76, 0xfd, 0xa4, 0xbd, 0x11, 0xea, 0xf5, 0x2c, 0x90, 0x12, 0xc0, 0x1c, 0xe3, 0x79, 0x19, 0xc1, 0x2f, 0x07, 0x0b, 0x25, 0x94, 0xf8, 0xc8, 0xac, 0x85, 0x87, 0xae, 0xbb, 0xe5, 0x24, 0xa8, 0x11, 0xeb, 0xc0, 0x46, 0x02, 0xa4, 0x39, 0xd3, 0xe6, 0xe1, 0x12, 0xfc, 0x60, 0x44, 0x5f, 0x68, 0x1d, 0x06, 0x6a, 0xcb, 0x26, 0x3e, 0xeb, 0xa3, 0xca, 0xba, 0x70, 0xb9, 0xd8, 0x32, 0x72, 0xf4, 0x26, 0x2c, 0x5d, 0x5d, 0xee, 0x75, 0x20, 0xf7, 0x52, 0xcc, 0x9c, 0x9f, 0x50, 0xf5, 0xb2, 0x2c, 0x67, 0x2e, 0x6b, 0xc1, 0xfd, 0x6c, 0xa0, 0x4b, 0x63, 0x52, 0xe7, 0xb0, 0x4a, 0xcb, 0x87, 0x2c, 0x73, 0x1c, 0xfe, 0xfb, 0xc6, 0xab, 0xb7, 0x81, 0x6d }; /* echo -n "mytbs" \ |openssl dgst -binary -sha256 \ |openssl rsautl -inkey testkeys/RSA/2048_RSA_KEY.pem -sign \ |xxd -i Note: this is a DigestInfoless signature (like the signatures used in TLS 1.1 and below, but with SHA-256 instead of MD5-SHA1. */ unsigned char expectedSig2[] = { 0x27, 0x05, 0x37, 0x60, 0x71, 0x8f, 0x96, 0x9c, 0xbc, 0xc7, 0x29, 0x65, 0xf5, 0xc7, 0x8e, 0xf4, 0x94, 0x8d, 0x2f, 0x23, 0xca, 0x88, 0xd1, 0x68, 0x16, 0x6b, 0xbe, 0x5b, 0x1c, 0x6a, 0x39, 0x59, 0xd0, 0x14, 0x77, 0x9c, 0x68, 0x7a, 0xab, 0x9c, 0x59, 0x19, 0x34, 0xaa, 0xe8, 0x52, 0x85, 0xc6, 0xef, 0x1c, 0xbe, 0x91, 0x0e, 0xfc, 0x93, 0x4c, 0xdb, 0x96, 0x82, 0x72, 0x7b, 0xc0, 0xdd, 0x4e, 0xcb, 0xf7, 0x24, 0xcc, 0xce, 0x2c, 0x52, 0x7c, 0xc3, 0x41, 0x0c, 0x07, 0xa4, 0xe1, 0x84, 0x61, 0xc0, 0x9c, 0xde, 0xda, 0x1b, 0x9b, 0x98, 0x9d, 0xc3, 0x0b, 0xc2, 0x25, 0x32, 0x6a, 0x15, 0x0b, 0xcc, 0x0f, 0x7b, 0x04, 0x1f, 0x7b, 0xc0, 0x25, 0x1b, 0x14, 0xca, 0x57, 0x95, 0x35, 0x25, 0xd5, 0xce, 0x63, 0xe5, 0xd6, 0x15, 0x32, 0x96, 0xd0, 0x0d, 0x13, 0x9d, 0x83, 0x80, 0x1f, 0xec, 0xc6, 0x71, 0x42, 0xee, 0x89, 0xa8, 0x2a, 0xc3, 0x1b, 0x72, 0x1c, 0xbb, 0x11, 0x88, 0x9c, 0x22, 0xd2, 0x49, 0x2e, 0xba, 0x84, 0xe6, 0x29, 0x88, 0x49, 0x24, 0x55, 0xc3, 0x97, 0xca, 0x4b, 0x73, 0xcd, 0xea, 0x21, 0x1f, 0x14, 0xab, 0xd4, 0x22, 0xb3, 0x63, 0x21, 0x3a, 0x7e, 0x76, 0xd9, 0xb2, 0x9a, 0xf8, 0xad, 0x43, 0x2a, 0xa2, 0x50, 0x09, 0x29, 0xeb, 0x1c, 0x45, 0x61, 0xfd, 0xae, 0x30, 0x7e, 0x64, 0x7e, 0xf1, 0x2f, 0x49, 0xf0, 0xbd, 0x7a, 0xc4, 0x89, 0x2d, 0xea, 0xf6, 0xd2, 0xef, 0xc2, 0x27, 0xca, 0xeb, 0x08, 0x7a, 0x44, 0x73, 0xca, 0xa8, 0x34, 0x26, 0x63, 0x1d, 0x77, 0xd9, 0x92, 0x86, 0x7a, 0xdf, 0xe7, 0xac, 0xb2, 0x7d, 0xcc, 0x4c, 0x5f, 0xdc, 0x0e, 0x7f, 0x66, 0x42, 0x56, 0xb2, 0x65, 0xe1, 0x56, 0xdc, 0xfe, 0xe8, 0xfc, 0x59, 0x8e, 0x00, 0x2f, 0xac, 0x99, 0xac, 0xb4 }; unsigned char *sig1 = NULL; psSize_t sigLen1; unsigned char *sig2 = NULL; psSize_t sigLen2; psPubKey_t privKey; psPubKey_t pubKey; int32_t rc; psRes_t rc2; psBool_t verifyOk; psVerifyOptions_t verifyOpts = {0}; /* Hash some data and sign the hash with 2048_RSA_KEY, then parse 2048_RSA_PUB from PEM and try to verify the signature. */ rc = psParseUnknownPrivKeyMem(NULL, RSA2048KEY, sizeof(RSA2048KEY), NULL, &privKey); if (rc != PS_RSA) { _psTrace("psParseUnknownPrivKey failed\n"); goto out_fail; } rc = psComputeHashForSig(tbs, tbsLen, OID_SHA256_RSA_SIG, hashTbs, &hashTbsLen); if (rc != PS_SUCCESS) { _psTrace("psComputeHashForSig failed\n"); goto out_fail; } /* OID_SHA256_RSA_SIG produces a PKCS #1.5 signature, where hashTbs is first wrapped into a DigestInfo. */ rc = psSign(NULL, &privKey, OID_SHA256_RSA_SIG, hashTbs, hashTbsLen, &sig1, &sigLen1, NULL); if (rc != PS_SUCCESS) { _psTrace("psSign failed for sig1\n"); goto out_fail; } if (sigLen1 != sizeof(expectedSig1)) { _psTrace("psSign output sig1 has wrong len\n"); goto out_fail; } if (Memcmp(sig1, expectedSig1, sigLen1)) { # ifdef DEBUG_ALGORITHM_TEST psTraceBytes("Got: ", sig1, sigLen1); psTraceBytes("Expected: ", expectedSig1, sigLen1); # endif _psTrace("psSign output sig1 is wrong\n"); goto out_fail; } /* OID_RSA_TLS_SIG_ALG produces a TLS 1.1 style signature (without DigestInfo encoding). */ rc = psSign(NULL, &privKey, OID_RSA_TLS_SIG_ALG, hashTbs, hashTbsLen, &sig2, &sigLen2, NULL); if (rc != PS_SUCCESS) { _psTrace("psSign failed for sig2\n"); goto out_fail; } if (sigLen2 != sizeof(expectedSig2)) { _psTrace("psSign output sig2 has wrong len\n"); goto out_fail; } if (Memcmp(sig2, expectedSig2, sigLen2)) { #ifdef DEBUG_ALGORITHM_TEST psTraceBytes("Got: ", sig2, sigLen2); psTraceBytes("Expected: ", expectedSig2, sigLen2); #endif _psTrace("psSign output sig2 is wrong\n"); goto out_fail; } psRsaInitKey(NULL, &pubKey.key.rsa); rc = psRsaParsePubKeyMem(NULL, RSA2048KEY_PUB_PEM, sizeof(RSA2048KEY_PUB_PEM), NULL, &pubKey.key.rsa); if (rc != PS_SUCCESS) { _psTrace("psRsaParsePubKeyMem failed\n"); goto out_fail; } pubKey.type = PS_RSA; verifyOpts.msgIsDigestInfo = PS_TRUE; rc2 = psVerify(NULL, tbs, tbsLen, sig1, sigLen1, &pubKey, OID_SHA256_RSA_SIG, &verifyOk, &verifyOpts); if (rc2 != PS_SUCCESS && !verifyOk) { _psTrace("psVerify failed for sig 1\n"); goto out_fail; } verifyOpts.msgIsDigestInfo = PS_FALSE; rc2 = psVerify(NULL, tbs, tbsLen, sig2, sigLen2, &pubKey, OID_SHA256_RSA_SIG, &verifyOk, &verifyOpts); if (rc2 != PS_SUCCESS && !verifyOk) { _psTrace("psVerify failed for sig 2\n"); goto out_fail; } /* Now corrupt the sig a bit and ensure verification fails. */ sig2[4] = 0x0a; verifyOpts.msgIsDigestInfo = PS_FALSE; rc2 = psVerify(NULL, tbs, tbsLen, sig2, sigLen2, &pubKey, OID_SHA256_RSA_SIG, &verifyOk, &verifyOpts); if (verifyOk || rc2 == PS_SUCCESS) { _psTrace("psVerify wrong result for corrupted sig 2\n"); goto out_fail; } psClearPubKey(&privKey); psRsaClearKey(&pubKey.key.rsa); psFree(sig1, NULL); psFree(sig2, NULL); _psTrace(" PASSED\n"); return PS_SUCCESS; out_fail: psFree(sig1, NULL); psFree(sig2, NULL); return PS_FAILURE; } # endif /* USE_RSA && USE_PEM_DECODE */ # endif /* USE_PRIVATE_KEY_PARSING */ /******************************************************************************/ # ifdef USE_PKCS1_OAEP /* OAEP-VEC.TXT from RSA PKCS#1 web page */ static unsigned char key1N[] = { 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 }; static unsigned char key1e[] = { 0x01, 0x00, 0x01 }; static unsigned char key1d[] = { 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 }; static unsigned char key1p[] = { 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 }; static unsigned char key1q[] = { 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 }; static unsigned char key1dP[] = { 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 }; static unsigned char key1dQ[] = { 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 }; static unsigned char key1qP[] = { 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 }; static unsigned char key1TestMsg[] = { 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34 }; static unsigned char key1SeedPad[] = { 0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, 0xdd, 0xa0, 0xa5, 0xef }; static unsigned char key1EncryptedResult[] = { 0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f, 0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb, 0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01, 0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f, 0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22, 0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26, 0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c, 0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a }; static int32 psRsaOaepVectorTest(void) { psPool_t *pool = NULL; psRsaKey_t key1; pstm_int mpN, mpe, mpd, mpp, mpq, mpdP, mpdQ, mpqP; uint32 digSize; psSize_t outLen; unsigned char *outOaep, *outRsaE, *outRsaD; int32 ret; outOaep = outRsaE = outRsaD = NULL; digSize = sizeof(pstm_digit); if (pstm_init_for_read_unsigned_bin(pool, &mpN, sizeof(key1N) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpN, key1N, sizeof(key1N)); if (pstm_init_for_read_unsigned_bin(pool, &mpe, sizeof(key1e) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpe, key1e, sizeof(key1e)); if (pstm_init_for_read_unsigned_bin(pool, &mpd, sizeof(key1d) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpd, key1d, sizeof(key1d)); if (pstm_init_for_read_unsigned_bin(pool, &mpp, sizeof(key1p) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpp, key1p, sizeof(key1p)); if (pstm_init_for_read_unsigned_bin(NULL, &mpq, sizeof(key1q) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpq, key1q, sizeof(key1q)); if (pstm_init_for_read_unsigned_bin(pool, &mpdP, sizeof(key1dP) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpdP, key1dP, sizeof(key1dP)); if (pstm_init_for_read_unsigned_bin(pool, &mpdQ, sizeof(key1dQ) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpdQ, key1dQ, sizeof(key1dQ)); if (pstm_init_for_read_unsigned_bin(pool, &mpqP, sizeof(key1qP) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpqP, key1qP, sizeof(key1qP)); key1.e = mpe; key1.N = mpN; key1.d = mpd; key1.p = mpp; key1.q = mpq; key1.dP = mpdP; key1.dQ = mpdQ; key1.qP = mpqP; key1.optimized = 1; outLen = key1.size = pstm_unsigned_bin_size(&mpN); outOaep = psMalloc(pool, outLen); psPkcs1OaepEncode(pool, key1TestMsg, sizeof(key1TestMsg), NULL, 0, key1SeedPad, sizeof(key1SeedPad), key1.size * CHAR_BIT, 0, outOaep, &outLen); outRsaE = psMalloc(pool, outLen); psRsaCrypt(pool, &key1, outOaep, outLen, outRsaE, &outLen, PS_PUBKEY, NULL); if (Memcmp(outRsaE, key1EncryptedResult, outLen) != 0) { _psTrace("ERROR in encrypting key1 RSAES_OAEP vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } outRsaD = psMalloc(pool, outLen); psRsaCrypt(pool, &key1, outRsaE, outLen, outRsaD, &outLen, PS_PRIVKEY, NULL); Memset(outOaep, 0x0, key1.size); psPkcs1OaepDecode(pool, outRsaD, outLen, NULL, 0, key1.size * CHAR_BIT, 0, outOaep, &outLen); if ((outLen != sizeof(key1TestMsg)) || (Memcmp(outOaep, key1TestMsg, outLen) != 0)) { _psTrace("ERROR in decrypting key1 RSAES_OAEP vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } /* Now just run a plaintext test of our choosing with the MD5 hash and label */ outLen = key1.size; if (psPkcs1OaepEncode(pool, (const unsigned char *) "Hello", 5, (const unsigned char *) "mylabel", 7, NULL, 0, key1.size * CHAR_BIT, 1, outOaep, &outLen) < PS_SUCCESS) { _psTrace("ERROR encoding standard RSAES_OAEP vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } psRsaCrypt(pool, &key1, outOaep, outLen, outRsaE, &outLen, PS_PUBKEY, NULL); psRsaCrypt(pool, &key1, outRsaE, outLen, outRsaD, &outLen, PS_PRIVKEY, NULL); psPkcs1OaepDecode(pool, outRsaD, outLen, (const unsigned char *) "mylabel", 7, key1.size * CHAR_BIT, 1, outOaep, &outLen); if (Memcmp(outOaep, "Hello", outLen) != 0) { _psTrace("ERROR in standard RSAES_OAEP vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } _psTrace(" PASSED\n"); ret = PS_SUCCESS; LBL_ERR: pstm_clear(&key1.N); pstm_clear(&key1.e); pstm_clear(&key1.d); pstm_clear(&key1.p); pstm_clear(&key1.q); pstm_clear(&key1.dP); pstm_clear(&key1.dQ); pstm_clear(&key1.qP); psFree(outOaep, pool); psFree(outRsaE, pool); psFree(outRsaD, pool); return ret; } # endif /* USE_PKCS1_OAEP */ /******************************************************************************/ # ifdef USE_PKCS1_PSS # ifndef USE_CL_RSA /* crypto-cl doesn't support the used API. */ # ifdef USE_SHA1 /* Test uses SHA-1. */ /* PSS-VEC.TXT from RSA PKCS#1 web page */ static unsigned char key2N[] = { 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51, 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77, 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3, 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8, 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 }; static unsigned char key2e[] = { 0x01, 0x00, 0x01 }; static unsigned char key2d[] = { 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51, 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf, 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f, 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44, 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10, 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27, 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e, 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc, 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 }; static unsigned char key2p[] = { 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73, 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa, 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96, 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb, 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b, 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e, 0xda, 0x8e, 0x64, 0x43 }; static unsigned char key2q[] = { 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7, 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f, 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48, 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba, 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e, 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26, 0x9a, 0x67, 0x99, 0xfd }; static unsigned char key2dP[] = { 0x28, 0xfa, 0x13, 0x93, 0x86, 0x55, 0xbe, 0x1f, 0x8a, 0x15, 0x9c, 0xba, 0xca, 0x5a, 0x72, 0xea, 0x19, 0x0c, 0x30, 0x08, 0x9e, 0x19, 0xcd, 0x27, 0x4a, 0x55, 0x6f, 0x36, 0xc4, 0xf6, 0xe1, 0x9f, 0x55, 0x4b, 0x34, 0xc0, 0x77, 0x79, 0x04, 0x27, 0xbb, 0xdd, 0x8d, 0xd3, 0xed, 0xe2, 0x44, 0x83, 0x28, 0xf3, 0x85, 0xd8, 0x1b, 0x30, 0xe8, 0xe4, 0x3b, 0x2f, 0xff, 0xa0, 0x27, 0x86, 0x19, 0x79 }; static unsigned char key2dQ[] = { 0x1a, 0x8b, 0x38, 0xf3, 0x98, 0xfa, 0x71, 0x20, 0x49, 0x89, 0x8d, 0x7f, 0xb7, 0x9e, 0xe0, 0xa7, 0x76, 0x68, 0x79, 0x12, 0x99, 0xcd, 0xfa, 0x09, 0xef, 0xc0, 0xe5, 0x07, 0xac, 0xb2, 0x1e, 0xd7, 0x43, 0x01, 0xef, 0x5b, 0xfd, 0x48, 0xbe, 0x45, 0x5e, 0xae, 0xb6, 0xe1, 0x67, 0x82, 0x55, 0x82, 0x75, 0x80, 0xa8, 0xe4, 0xe8, 0xe1, 0x41, 0x51, 0xd1, 0x51, 0x0a, 0x82, 0xa3, 0xf2, 0xe7, 0x29 }; static unsigned char key2qP[] = { 0x27, 0x15, 0x6a, 0xba, 0x41, 0x26, 0xd2, 0x4a, 0x81, 0xf3, 0xa5, 0x28, 0xcb, 0xfb, 0x27, 0xf5, 0x68, 0x86, 0xf8, 0x40, 0xa9, 0xf6, 0xe8, 0x6e, 0x17, 0xa4, 0x4b, 0x94, 0xfe, 0x93, 0x19, 0x58, 0x4b, 0x8e, 0x22, 0xfd, 0xde, 0x1e, 0x5a, 0x2e, 0x3b, 0xd8, 0xaa, 0x5b, 0xa8, 0xd8, 0x58, 0x41, 0x94, 0xeb, 0x21, 0x90, 0xac, 0xf8, 0x32, 0xb8, 0x47, 0xf1, 0x3a, 0x3d, 0x24, 0xa7, 0x9f, 0x4d }; static unsigned char key2TestMsg[] = { 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 }; static unsigned char key2salt[] = { 0xde, 0xe9, 0x59, 0xc7, 0xe0, 0x64, 0x11, 0x36, 0x14, 0x20, 0xff, 0x80, 0x18, 0x5e, 0xd5, 0x7f, 0x3e, 0x67, 0x76, 0xaf }; static unsigned char key2sig[] = { 0x90, 0x74, 0x30, 0x8f, 0xb5, 0x98, 0xe9, 0x70, 0x1b, 0x22, 0x94, 0x38, 0x8e, 0x52, 0xf9, 0x71, 0xfa, 0xac, 0x2b, 0x60, 0xa5, 0x14, 0x5a, 0xf1, 0x85, 0xdf, 0x52, 0x87, 0xb5, 0xed, 0x28, 0x87, 0xe5, 0x7c, 0xe7, 0xfd, 0x44, 0xdc, 0x86, 0x34, 0xe4, 0x07, 0xc8, 0xe0, 0xe4, 0x36, 0x0b, 0xc2, 0x26, 0xf3, 0xec, 0x22, 0x7f, 0x9d, 0x9e, 0x54, 0x63, 0x8e, 0x8d, 0x31, 0xf5, 0x05, 0x12, 0x15, 0xdf, 0x6e, 0xbb, 0x9c, 0x2f, 0x95, 0x79, 0xaa, 0x77, 0x59, 0x8a, 0x38, 0xf9, 0x14, 0xb5, 0xb9, 0xc1, 0xbd, 0x83, 0xc4, 0xe2, 0xf9, 0xf3, 0x82, 0xa0, 0xd0, 0xaa, 0x35, 0x42, 0xff, 0xee, 0x65, 0x98, 0x4a, 0x60, 0x1b, 0xc6, 0x9e, 0xb2, 0x8d, 0xeb, 0x27, 0xdc, 0xa1, 0x2c, 0x82, 0xc2, 0xd4, 0xc3, 0xf6, 0x6c, 0xd5, 0x00, 0xf1, 0xff, 0x2b, 0x99, 0x4d, 0x8a, 0x4e, 0x30, 0xcb, 0xb3, 0x3c }; static int32 psRsaPssVectorTest(void) { # ifdef USE_ROT_RSA _psTrace("SKIPPED\n"); return PS_SUCCESS; # else psPool_t *pool = NULL; psRsaKey_t key1; pstm_int mpN, mpe, mpd, mpp, mpq, mpdP, mpdQ, mpqP; uint32 digSize, outLen; psSize_t outLen16; unsigned char *outPss, *outRsaE, *outRsaD; psSha1_t md; unsigned char hash[SHA1_HASH_SIZE]; int32 result, ret; outPss = outRsaE = outRsaD = NULL; digSize = sizeof(pstm_digit); if (pstm_init_for_read_unsigned_bin(pool, &mpN, sizeof(key2N) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpN, key2N, sizeof(key2N)); if (pstm_init_for_read_unsigned_bin(pool, &mpe, sizeof(key2e) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpe, key2e, sizeof(key2e)); if (pstm_init_for_read_unsigned_bin(pool, &mpd, sizeof(key2d) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpd, key2d, sizeof(key2d)); if (pstm_init_for_read_unsigned_bin(pool, &mpp, sizeof(key2p) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpp, key2p, sizeof(key2p)); if (pstm_init_for_read_unsigned_bin(pool, &mpq, sizeof(key2q) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpq, key2q, sizeof(key2q)); if (pstm_init_for_read_unsigned_bin(pool, &mpdP, sizeof(key2dP) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpdP, key2dP, sizeof(key2dP)); if (pstm_init_for_read_unsigned_bin(pool, &mpdQ, sizeof(key2dQ) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpdQ, key2dQ, sizeof(key2dQ)); if (pstm_init_for_read_unsigned_bin(pool, &mpqP, sizeof(key2qP) + digSize) != PS_SUCCESS) { return PS_FAILURE; } pstm_read_unsigned_bin(&mpqP, key2qP, sizeof(key2qP)); key1.e = mpe; key1.N = mpN; key1.d = mpd; key1.p = mpp; key1.q = mpq; key1.dP = mpdP; key1.dQ = mpdQ; key1.qP = mpqP; key1.optimized = 1; outLen = key1.size = pstm_unsigned_bin_size(&mpN); /* First take SHA-1 hash of test message */ psSha1Init(&md); psSha1Update(&md, key2TestMsg, sizeof(key2TestMsg)); psSha1Final(&md, hash); /* Then PSS */ outPss = psMalloc(pool, outLen); outLen16 = (uint16_t) outLen; psPkcs1PssEncode(pool, hash, SHA1_HASH_SIZE, key2salt, sizeof(key2salt), 0, key1.size * CHAR_BIT, outPss, &outLen16); outLen = outLen16; outRsaE = psMalloc(pool, outLen); /* Then sign */ psRsaCrypt(pool, &key1, outPss, outLen, outRsaE, &outLen16, PS_PRIVKEY, NULL); outLen = outLen16; /* Check against vector */ if (Memcmp(outRsaE, key2sig, outLen) != 0) { _psTrace("ERROR in encrypting key1 RSASSA_PSS vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } /* Verify */ outRsaD = psMalloc(pool, outLen); /* Decrypt */ outLen16 = (uint16_t) outLen; psRsaCrypt(pool, &key1, outRsaE, outLen, outRsaD, &outLen16, PS_PUBKEY, NULL); outLen = outLen16; /* PSS decode */ psPkcs1PssDecode(pool, hash, SHA1_HASH_SIZE, outRsaD, outLen, sizeof(key2salt), 0, key1.size * CHAR_BIT, &result); if (result != 1) { _psTrace("ERROR in decrypting key1 RSASSA_PSS vector test\n"); ret = PS_FAILURE; goto LBL_ERR; } _psTrace(" PASSED\n"); ret = PS_SUCCESS; LBL_ERR: pstm_clear(&key1.N); pstm_clear(&key1.e); pstm_clear(&key1.d); pstm_clear(&key1.p); pstm_clear(&key1.q); pstm_clear(&key1.dP); pstm_clear(&key1.dQ); pstm_clear(&key1.qP); psFree(outRsaD, pool); psFree(outPss, pool); psFree(outRsaE, pool); return ret; # endif /* USE_ROT_RSA */ } # endif /* USE_SHA1 */ # endif /* USE_CL_RSA */ # endif /* USE_PKCS1_PSS */ #endif /* USE_RSA */ #ifdef USE_HMAC # ifdef USE_HMAC_TLS static int nohmactls = 0; # endif # ifdef USE_HMAC_SHA1 static int32 psHmacVectorTestSimple(void) { unsigned char res[20]; unsigned char res2[20]; psHmacSha1_t ctx; int32_t rv; const char *data1 = "Hi There"; unsigned char key1[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; const unsigned char res1[] = { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00 }; psSize_t keyLen = (uint16_t) sizeof(key1); _psTraceInt(" SHA-1 known vector test %d... ", 1); /* Try single-call */ rv = psHmacSha1(key1, keyLen, (unsigned char *) data1, (uint32_t) Strlen(data1), res2, key1, &keyLen); if (rv != PS_SUCCESS) { _psTraceInt("FAILED: Single-part HMAC KAT execution failure (rv=%d)\n", (int) rv); return PS_FAILURE; } if (Memcmp(res1, res2, 20) != 0) { _psTrace("FAILED: Single-part HMAC KAT mismatch\n"); return PS_FAILURE; } # ifdef USE_HMAC_TLS /* Try single-call */ Memset(res2, 0, 20); rv = psHmacSha1Tls(key1, keyLen, (unsigned char *) data1, 2, (unsigned char *) data1 + 2, 4, (unsigned char *) data1 + 6, 2, 2, res2); if (rv == PS_DISABLED_FEATURE_FAIL) { nohmactls = 1; } else if (rv != SHA1_HASH_SIZE) { _psTraceInt("FAILED: Single-part HMAC KAT execution failure (rv=%d)\n", (int) rv); return PS_FAILURE; } else if (Memcmp(res1, res2, 20) != 0) { _psTrace("FAILED: Single-part HMAC KAT mismatch\n"); return PS_FAILURE; } # endif /* USE_HMAC_TLS */ /* Try init-update-finish */ rv = psHmacSha1Init(&ctx, key1, keyLen); psHmacSha1Update(&ctx, (unsigned char *) data1, (uint32_t) Strlen(data1)); (void) psHmacSha1Final(&ctx, res); if (Memcmp(res, res1, 20) != 0) { _psTrace("FAILED: Init-Update-Finish HMAC KAT mismatch\n"); } _psTrace("PASSED\n"); return PS_SUCCESS; } # endif /* USE_HMAC_SHA1 */ static int test_hmac_vector_num_calls; static int test_hmac_vector(int32 size, const unsigned char *key, size_t key_len, const unsigned char *din, size_t din_len, const unsigned char *dout, size_t dout_len, int32 should_succeed) { unsigned char key_out[128]; unsigned char md_res[64]; uint16_t key_length = 0; int equals; int32 rv = PS_SUCCESS; # ifdef USE_HMAC_SHA1 psHmacSha1_t hmac_sha1_ctx; # endif /* USE_HMAC_SHA1 */ # ifdef USE_HMAC_SHA256 psHmacSha256_t hmac_sha256_ctx; # endif /* USE_HMAC_SHA256 */ # ifdef USE_HMAC_SHA384 psHmacSha384_t hmac_sha384_ctx; # endif /* USE_HMAC_SHA384 */ ++test_hmac_vector_num_calls; /* Copy key, if it is short as short ones are not normally copied. */ if (key_len <= 128) { Memcpy(key_out, key, key_len); key = key_out; } key_length = (uint16_t) key_len; psAssert(size == 20 || size == 28 || size == 32 || size == 48); # ifdef USE_HMAC_SHA1 if (size == 20) { rv = psHmacSha1((unsigned char *) key, key_length, din, din_len, md_res, key_out, &key_length); } else # endif /* USE_HMAC_SHA1 */ # ifdef USE_HMAC_SHA256 if (size == 32) { rv = psHmacSha256((unsigned char *) key, key_length, din, din_len, md_res, key_out, &key_length); } else # endif /* USE_HMAC_SHA256 */ # ifdef USE_HMAC_SHA384 if (size == 48) { rv = psHmacSha384((unsigned char *) key, key_length, din, din_len, md_res, key_out, &key_length); } else # endif /* USE_HMAC_SHA384 */ { _psTraceInt("FAILED: HMAC vector unsupported size: %d\n", (int) size); return PS_FAILURE; } equals = (rv == PS_SUCCESS && Memcmp(dout, md_res, size) == 0); if (equals != should_succeed) { _psTraceInt("FAILED: HMAC vector with %d bit key\n", 8 * (int) key_len); return PS_FAILURE; } Memset(md_res, 0, sizeof(md_res)); # ifdef USE_HMAC_SHA1 if (size == 20) { rv = psHmacSha1Init(&hmac_sha1_ctx, key_out, key_length); psHmacSha1Update(&hmac_sha1_ctx, din, din_len); psHmacSha1Final(&hmac_sha1_ctx, md_res); } else # endif /* USE_HMAC_SHA1 */ # ifdef USE_HMAC_SHA256 if (size == 32) { rv = psHmacSha256Init(&hmac_sha256_ctx, key_out, key_length); psHmacSha256Update(&hmac_sha256_ctx, din, din_len); psHmacSha256Final(&hmac_sha256_ctx, md_res); } else # endif /* USE_HMAC_SHA256 */ # ifdef USE_HMAC_SHA384 if (size == 48) { rv = psHmacSha384Init(&hmac_sha384_ctx, key_out, key_length); psHmacSha384Update(&hmac_sha384_ctx, din, din_len); psHmacSha384Final(&hmac_sha384_ctx, md_res); } # endif /* USE_HMAC_SHA384 */ equals = (rv == PS_SUCCESS && Memcmp(dout, md_res, size) == 0); if (equals != should_succeed) { _psTraceInt("FAILED: HMAC vector with %d bit key (multipart op)\n", 8 * (int) key_len); return PS_FAILURE; } # ifdef USE_HMAC_TLS /* Try single-call if suitable vector size. */ if (size == 20 || din_len < 13 || key_len > 64 || nohmactls == 1) { return 1; } Memset(md_res, 0, sizeof(md_res)); if (din_len < 64) { int i; /* use tmp to get enough allocation for din (-lasan) */ unsigned char tmp[164]; Memcpy(tmp, din, din_len); for (i = 0; i < 100; i++) { rv = psHmacSha2Tls(key, key_len, (unsigned char *) tmp, 8, (unsigned char *) tmp + 8, 5, (unsigned char *) tmp + 13, din_len - 13, din_len - 13 + i, md_res, size); if (rv != size) { _psTraceInt( "FAILED: Single-part HMAC KAT execution failure (rv=%d)\n", (int) rv); return PS_FAILURE; } if (Memcmp(dout, md_res, size) != 0) { _psTrace("FAILED: Single-part HMAC KAT mismatch\n"); return PS_FAILURE; } } } else { rv = psHmacSha2Tls(key, key_len, (unsigned char *) din, 8, (unsigned char *) din + 8, 5, (unsigned char *) din + 13, din_len - 13, din_len - 13, md_res, size); } if (rv != size) { _psTraceInt("FAILED: Single-part HMAC KAT execution failure (rv=%d)\n", (int) rv); return PS_FAILURE; } if (Memcmp(dout, md_res, size) != 0) { _psTrace("FAILED: Single-part HMAC KAT mismatch\n"); return PS_FAILURE; } # endif /* USE_HMAC_TLS */ return 1; } static int32 psHmacVectorTestsShared(int algo) { int32 md; int32 e = 1; int32 res = PS_SUCCESS; int32 count = 0; /* SHA-1 */ if (algo != 20) { goto sha2_224; } md = algo; /* key size: 14 bytes */ count += test_hmac_vector(md, hmac_sha1_vector14_key, sizeof(hmac_sha1_vector14_key), hmac_sha1_vector14_in, sizeof(hmac_sha1_vector14_in), hmac_sha1_vector14_out, sizeof(hmac_sha1_vector14_out), e); /* key size: 16 bytes */ count += test_hmac_vector(md, hmac_sha1_vector16_key, sizeof(hmac_sha1_vector16_key), hmac_sha1_vector16_in, sizeof(hmac_sha1_vector16_in), hmac_sha1_vector16_out, sizeof(hmac_sha1_vector16_out), e); /* key size: 20 bytes */ count += test_hmac_vector(md, hmac_sha1_vector20_key, sizeof(hmac_sha1_vector20_key), hmac_sha1_vector20_in, sizeof(hmac_sha1_vector20_in), hmac_sha1_vector20_out, sizeof(hmac_sha1_vector20_out), e); /* key size: 24 bytes */ count += test_hmac_vector(md, hmac_sha1_vector24_key, sizeof(hmac_sha1_vector24_key), hmac_sha1_vector24_in, sizeof(hmac_sha1_vector24_in), hmac_sha1_vector24_out, sizeof(hmac_sha1_vector24_out), e); /* key size: 28 bytes */ count += test_hmac_vector(md, hmac_sha1_vector28_key, sizeof(hmac_sha1_vector28_key), hmac_sha1_vector28_in, sizeof(hmac_sha1_vector28_in), hmac_sha1_vector28_out, sizeof(hmac_sha1_vector28_out), e); /* key size: 32 bytes */ count += test_hmac_vector(md, hmac_sha1_vector32_key, sizeof(hmac_sha1_vector32_key), hmac_sha1_vector32_in, sizeof(hmac_sha1_vector32_in), hmac_sha1_vector32_out, sizeof(hmac_sha1_vector32_out), e); /* key size: 48 bytes */ count += test_hmac_vector(md, hmac_sha1_vector48_key, sizeof(hmac_sha1_vector48_key), hmac_sha1_vector48_in, sizeof(hmac_sha1_vector48_in), hmac_sha1_vector48_out, sizeof(hmac_sha1_vector48_out), e); /* key size: 64 bytes */ count += test_hmac_vector(md, hmac_sha1_vector64_key, sizeof(hmac_sha1_vector64_key), hmac_sha1_vector64_in, sizeof(hmac_sha1_vector64_in), hmac_sha1_vector64_out, sizeof(hmac_sha1_vector64_out), e); /* key size: 128 bytes */ count += test_hmac_vector(md, hmac_sha1_vector128_key, sizeof(hmac_sha1_vector128_key), hmac_sha1_vector128_in, sizeof(hmac_sha1_vector128_in), hmac_sha1_vector128_out, sizeof(hmac_sha1_vector128_out), e); /* key size: 256 bytes */ count += test_hmac_vector(md, hmac_sha1_vector256_key, sizeof(hmac_sha1_vector256_key), hmac_sha1_vector256_in, sizeof(hmac_sha1_vector256_in), hmac_sha1_vector256_out, sizeof(hmac_sha1_vector256_out), e); /* key size: 512 bytes */ count += test_hmac_vector(md, hmac_sha1_vector512_key, sizeof(hmac_sha1_vector512_key), hmac_sha1_vector512_in, sizeof(hmac_sha1_vector512_in), hmac_sha1_vector512_out, sizeof(hmac_sha1_vector512_out), e); /* key size: 1024 bytes */ count += test_hmac_vector(md, hmac_sha1_vector1024_key, sizeof(hmac_sha1_vector1024_key), hmac_sha1_vector1024_in, sizeof(hmac_sha1_vector1024_in), hmac_sha1_vector1024_out, sizeof(hmac_sha1_vector1024_out), e); /* multiblock test */ count += test_hmac_vector(md, hmac_vector1024_multiblock_key, sizeof(hmac_vector1024_multiblock_key), hmac_vector1024_multiblock_in, sizeof(hmac_vector1024_multiblock_in), hmac_sha1_vector1024_multiblock_out, sizeof(hmac_sha1_vector1024_multiblock_out), e); /* SHA-224 */ sha2_224: if (algo != 28) { goto sha2_256; } md = algo; /* key size: 14 bytes */ count += test_hmac_vector(md, hmac_sha224_vector14_key, sizeof(hmac_sha224_vector14_key), hmac_sha224_vector14_in, sizeof(hmac_sha224_vector14_in), hmac_sha224_vector14_out, sizeof(hmac_sha224_vector14_out), e); /* key size: 16 bytes */ count += test_hmac_vector(md, hmac_sha224_vector16_key, sizeof(hmac_sha224_vector16_key), hmac_sha224_vector16_in, sizeof(hmac_sha224_vector16_in), hmac_sha224_vector16_out, sizeof(hmac_sha224_vector16_out), e); /* key size: 20 bytes */ count += test_hmac_vector(md, hmac_sha224_vector20_key, sizeof(hmac_sha224_vector20_key), hmac_sha224_vector20_in, sizeof(hmac_sha224_vector20_in), hmac_sha224_vector20_out, sizeof(hmac_sha224_vector20_out), e); /* key size: 24 bytes */ count += test_hmac_vector(md, hmac_sha224_vector24_key, sizeof(hmac_sha224_vector24_key), hmac_sha224_vector24_in, sizeof(hmac_sha224_vector24_in), hmac_sha224_vector24_out, sizeof(hmac_sha224_vector24_out), e); /* key size: 28 bytes */ count += test_hmac_vector(md, hmac_sha224_vector28_key, sizeof(hmac_sha224_vector28_key), hmac_sha224_vector28_in, sizeof(hmac_sha224_vector28_in), hmac_sha224_vector28_out, sizeof(hmac_sha224_vector28_out), e); /* key size: 32 bytes */ count += test_hmac_vector(md, hmac_sha224_vector32_key, sizeof(hmac_sha224_vector32_key), hmac_sha224_vector32_in, sizeof(hmac_sha224_vector32_in), hmac_sha224_vector32_out, sizeof(hmac_sha224_vector32_out), e); /* key size: 48 bytes */ count += test_hmac_vector(md, hmac_sha224_vector48_key, sizeof(hmac_sha224_vector48_key), hmac_sha224_vector48_in, sizeof(hmac_sha224_vector48_in), hmac_sha224_vector48_out, sizeof(hmac_sha224_vector48_out), e); /* key size: 64 bytes */ count += test_hmac_vector(md, hmac_sha224_vector64_key, sizeof(hmac_sha224_vector64_key), hmac_sha224_vector64_in, sizeof(hmac_sha224_vector64_in), hmac_sha224_vector64_out, sizeof(hmac_sha224_vector64_out), e); /* key size: 128 bytes */ count += test_hmac_vector(md, hmac_sha224_vector128_key, sizeof(hmac_sha224_vector128_key), hmac_sha224_vector128_in, sizeof(hmac_sha224_vector128_in), hmac_sha224_vector128_out, sizeof(hmac_sha224_vector128_out), e); /* key size: 256 bytes */ count += test_hmac_vector(md, hmac_sha224_vector256_key, sizeof(hmac_sha224_vector256_key), hmac_sha224_vector256_in, sizeof(hmac_sha224_vector256_in), hmac_sha224_vector256_out, sizeof(hmac_sha224_vector256_out), e); /* key size: 512 bytes */ count += test_hmac_vector(md, hmac_sha224_vector512_key, sizeof(hmac_sha224_vector512_key), hmac_sha224_vector512_in, sizeof(hmac_sha224_vector512_in), hmac_sha224_vector512_out, sizeof(hmac_sha224_vector512_out), e); /* key size: 1024 bytes */ count += test_hmac_vector(md, hmac_sha224_vector1024_key, sizeof(hmac_sha224_vector1024_key), hmac_sha224_vector1024_in, sizeof(hmac_sha224_vector1024_in), hmac_sha224_vector1024_out, sizeof(hmac_sha224_vector1024_out), e); /* multiblock test */ count += test_hmac_vector(md, hmac_vector1024_multiblock_key, sizeof(hmac_vector1024_multiblock_key), hmac_vector1024_multiblock_in, sizeof(hmac_vector1024_multiblock_in), hmac_sha224_vector1024_multiblock_out, sizeof(hmac_sha224_vector1024_multiblock_out), e); /* SHA-256 */ sha2_256: if (algo != 32) { goto sha2_384; } md = algo; /* key size: 14 bytes */ count += test_hmac_vector(md, hmac_sha256_vector14_key, sizeof(hmac_sha256_vector14_key), hmac_sha256_vector14_in, sizeof(hmac_sha256_vector14_in), hmac_sha256_vector14_out, sizeof(hmac_sha256_vector14_out), e); /* key size: 16 bytes */ count += test_hmac_vector(md, hmac_sha256_vector16_key, sizeof(hmac_sha256_vector16_key), hmac_sha256_vector16_in, sizeof(hmac_sha256_vector16_in), hmac_sha256_vector16_out, sizeof(hmac_sha256_vector16_out), e); /* key size: 20 bytes */ count += test_hmac_vector(md, hmac_sha256_vector20_key, sizeof(hmac_sha256_vector20_key), hmac_sha256_vector20_in, sizeof(hmac_sha256_vector20_in), hmac_sha256_vector20_out, sizeof(hmac_sha256_vector20_out), e); /* key size: 24 bytes */ count += test_hmac_vector(md, hmac_sha256_vector24_key, sizeof(hmac_sha256_vector24_key), hmac_sha256_vector24_in, sizeof(hmac_sha256_vector24_in), hmac_sha256_vector24_out, sizeof(hmac_sha256_vector24_out), e); /* key size: 28 bytes */ count += test_hmac_vector(md, hmac_sha256_vector28_key, sizeof(hmac_sha256_vector28_key), hmac_sha256_vector28_in, sizeof(hmac_sha256_vector28_in), hmac_sha256_vector28_out, sizeof(hmac_sha256_vector28_out), e); /* key size: 32 bytes */ count += test_hmac_vector(md, hmac_sha256_vector32_key, sizeof(hmac_sha256_vector32_key), hmac_sha256_vector32_in, sizeof(hmac_sha256_vector32_in), hmac_sha256_vector32_out, sizeof(hmac_sha256_vector32_out), e); /* key size: 48 bytes */ count += test_hmac_vector(md, hmac_sha256_vector48_key, sizeof(hmac_sha256_vector48_key), hmac_sha256_vector48_in, sizeof(hmac_sha256_vector48_in), hmac_sha256_vector48_out, sizeof(hmac_sha256_vector48_out), e); /* key size: 64 bytes */ count += test_hmac_vector(md, hmac_sha256_vector64_key, sizeof(hmac_sha256_vector64_key), hmac_sha256_vector64_in, sizeof(hmac_sha256_vector64_in), hmac_sha256_vector64_out, sizeof(hmac_sha256_vector64_out), e); /* key size: 128 bytes */ count += test_hmac_vector(md, hmac_sha256_vector128_key, sizeof(hmac_sha256_vector128_key), hmac_sha256_vector128_in, sizeof(hmac_sha256_vector128_in), hmac_sha256_vector128_out, sizeof(hmac_sha256_vector128_out), e); /* key size: 256 bytes */ count += test_hmac_vector(md, hmac_sha256_vector256_key, sizeof(hmac_sha256_vector256_key), hmac_sha256_vector256_in, sizeof(hmac_sha256_vector256_in), hmac_sha256_vector256_out, sizeof(hmac_sha256_vector256_out), e); /* key size: 512 bytes */ count += test_hmac_vector(md, hmac_sha256_vector512_key, sizeof(hmac_sha256_vector512_key), hmac_sha256_vector512_in, sizeof(hmac_sha256_vector512_in), hmac_sha256_vector512_out, sizeof(hmac_sha256_vector512_out), e); /* key size: 1024 bytes */ count += test_hmac_vector(md, hmac_sha256_vector1024_key, sizeof(hmac_sha256_vector1024_key), hmac_sha256_vector1024_in, sizeof(hmac_sha256_vector1024_in), hmac_sha256_vector1024_out, sizeof(hmac_sha256_vector1024_out), e); /* multiblock test */ count += test_hmac_vector(md, hmac_vector1024_multiblock_key, sizeof(hmac_vector1024_multiblock_key), hmac_vector1024_multiblock_in, sizeof(hmac_vector1024_multiblock_in), hmac_sha256_vector1024_multiblock_out, sizeof(hmac_sha256_vector1024_multiblock_out), e); /* SHA-384 */ sha2_384: if (algo != 48) { goto sha2_512; } md = algo; /* key size: 14 bytes */ count += test_hmac_vector(md, hmac_sha384_vector14_key, sizeof(hmac_sha384_vector14_key), hmac_sha384_vector14_in, sizeof(hmac_sha384_vector14_in), hmac_sha384_vector14_out, sizeof(hmac_sha384_vector14_out), e); /* key size: 16 bytes */ count += test_hmac_vector(md, hmac_sha384_vector16_key, sizeof(hmac_sha384_vector16_key), hmac_sha384_vector16_in, sizeof(hmac_sha384_vector16_in), hmac_sha384_vector16_out, sizeof(hmac_sha384_vector16_out), e); /* key size: 20 bytes */ count += test_hmac_vector(md, hmac_sha384_vector20_key, sizeof(hmac_sha384_vector20_key), hmac_sha384_vector20_in, sizeof(hmac_sha384_vector20_in), hmac_sha384_vector20_out, sizeof(hmac_sha384_vector20_out), e); /* key size: 24 bytes */ count += test_hmac_vector(md, hmac_sha384_vector24_key, sizeof(hmac_sha384_vector24_key), hmac_sha384_vector24_in, sizeof(hmac_sha384_vector24_in), hmac_sha384_vector24_out, sizeof(hmac_sha384_vector24_out), e); /* key size: 28 bytes */ count += test_hmac_vector(md, hmac_sha384_vector28_key, sizeof(hmac_sha384_vector28_key), hmac_sha384_vector28_in, sizeof(hmac_sha384_vector28_in), hmac_sha384_vector28_out, sizeof(hmac_sha384_vector28_out), e); /* key size: 32 bytes */ count += test_hmac_vector(md, hmac_sha384_vector32_key, sizeof(hmac_sha384_vector32_key), hmac_sha384_vector32_in, sizeof(hmac_sha384_vector32_in), hmac_sha384_vector32_out, sizeof(hmac_sha384_vector32_out), e); /* key size: 48 bytes */ count += test_hmac_vector(md, hmac_sha384_vector48_key, sizeof(hmac_sha384_vector48_key), hmac_sha384_vector48_in, sizeof(hmac_sha384_vector48_in), hmac_sha384_vector48_out, sizeof(hmac_sha384_vector48_out), e); /* key size: 64 bytes */ count += test_hmac_vector(md, hmac_sha384_vector64_key, sizeof(hmac_sha384_vector64_key), hmac_sha384_vector64_in, sizeof(hmac_sha384_vector64_in), hmac_sha384_vector64_out, sizeof(hmac_sha384_vector64_out), e); /* key size: 128 bytes */ count += test_hmac_vector(md, hmac_sha384_vector128_key, sizeof(hmac_sha384_vector128_key), hmac_sha384_vector128_in, sizeof(hmac_sha384_vector128_in), hmac_sha384_vector128_out, sizeof(hmac_sha384_vector128_out), e); /* key size: 256 bytes */ count += test_hmac_vector(md, hmac_sha384_vector256_key, sizeof(hmac_sha384_vector256_key), hmac_sha384_vector256_in, sizeof(hmac_sha384_vector256_in), hmac_sha384_vector256_out, sizeof(hmac_sha384_vector256_out), e); /* key size: 512 bytes */ count += test_hmac_vector(md, hmac_sha384_vector512_key, sizeof(hmac_sha384_vector512_key), hmac_sha384_vector512_in, sizeof(hmac_sha384_vector512_in), hmac_sha384_vector512_out, sizeof(hmac_sha384_vector512_out), e); /* key size: 1024 bytes */ count += test_hmac_vector(md, hmac_sha384_vector1024_key, sizeof(hmac_sha384_vector1024_key), hmac_sha384_vector1024_in, sizeof(hmac_sha384_vector1024_in), hmac_sha384_vector1024_out, sizeof(hmac_sha384_vector1024_out), e); /* multiblock test */ count += test_hmac_vector(md, hmac_vector1024_multiblock_key, sizeof(hmac_vector1024_multiblock_key), hmac_vector1024_multiblock_in, sizeof(hmac_vector1024_multiblock_in), hmac_sha384_vector1024_multiblock_out, sizeof(hmac_sha384_vector1024_multiblock_out), e); /* SHA-512 */ sha2_512: if (algo != 64) { goto sha_finish; } md = algo; /* key size: 14 bytes */ count += test_hmac_vector(md, hmac_sha512_vector14_key, sizeof(hmac_sha512_vector14_key), hmac_sha512_vector14_in, sizeof(hmac_sha512_vector14_in), hmac_sha512_vector14_out, sizeof(hmac_sha512_vector14_out), e); /* key size: 16 bytes */ count += test_hmac_vector(md, hmac_sha512_vector16_key, sizeof(hmac_sha512_vector16_key), hmac_sha512_vector16_in, sizeof(hmac_sha512_vector16_in), hmac_sha512_vector16_out, sizeof(hmac_sha512_vector16_out), e); /* key size: 20 bytes */ count += test_hmac_vector(md, hmac_sha512_vector20_key, sizeof(hmac_sha512_vector20_key), hmac_sha512_vector20_in, sizeof(hmac_sha512_vector20_in), hmac_sha512_vector20_out, sizeof(hmac_sha512_vector20_out), e); /* key size: 24 bytes */ count += test_hmac_vector(md, hmac_sha512_vector24_key, sizeof(hmac_sha512_vector24_key), hmac_sha512_vector24_in, sizeof(hmac_sha512_vector24_in), hmac_sha512_vector24_out, sizeof(hmac_sha512_vector24_out), e); /* key size: 28 bytes */ count += test_hmac_vector(md, hmac_sha512_vector28_key, sizeof(hmac_sha512_vector28_key), hmac_sha512_vector28_in, sizeof(hmac_sha512_vector28_in), hmac_sha512_vector28_out, sizeof(hmac_sha512_vector28_out), e); /* key size: 32 bytes */ count += test_hmac_vector(md, hmac_sha512_vector32_key, sizeof(hmac_sha512_vector32_key), hmac_sha512_vector32_in, sizeof(hmac_sha512_vector32_in), hmac_sha512_vector32_out, sizeof(hmac_sha512_vector32_out), e); /* key size: 48 bytes */ count += test_hmac_vector(md, hmac_sha512_vector48_key, sizeof(hmac_sha512_vector48_key), hmac_sha512_vector48_in, sizeof(hmac_sha512_vector48_in), hmac_sha512_vector48_out, sizeof(hmac_sha512_vector48_out), e); /* key size: 64 bytes */ count += test_hmac_vector(md, hmac_sha512_vector64_key, sizeof(hmac_sha512_vector64_key), hmac_sha512_vector64_in, sizeof(hmac_sha512_vector64_in), hmac_sha512_vector64_out, sizeof(hmac_sha512_vector64_out), e); /* key size: 128 bytes */ count += test_hmac_vector(md, hmac_sha512_vector128_key, sizeof(hmac_sha512_vector128_key), hmac_sha512_vector128_in, sizeof(hmac_sha512_vector128_in), hmac_sha512_vector128_out, sizeof(hmac_sha512_vector128_out), e); /* key size: 256 bytes */ count += test_hmac_vector(md, hmac_sha512_vector256_key, sizeof(hmac_sha512_vector256_key), hmac_sha512_vector256_in, sizeof(hmac_sha512_vector256_in), hmac_sha512_vector256_out, sizeof(hmac_sha512_vector256_out), e); /* key size: 512 bytes */ count += test_hmac_vector(md, hmac_sha512_vector512_key, sizeof(hmac_sha512_vector512_key), hmac_sha512_vector512_in, sizeof(hmac_sha512_vector512_in), hmac_sha512_vector512_out, sizeof(hmac_sha512_vector512_out), e); /* key size: 1024 bytes */ count += test_hmac_vector(md, hmac_sha512_vector1024_key, sizeof(hmac_sha512_vector1024_key), hmac_sha512_vector1024_in, sizeof(hmac_sha512_vector1024_in), hmac_sha512_vector1024_out, sizeof(hmac_sha512_vector1024_out), e); /* multiblock test */ count += test_hmac_vector(md, hmac_vector1024_multiblock_key, sizeof(hmac_vector1024_multiblock_key), hmac_vector1024_multiblock_in, sizeof(hmac_vector1024_multiblock_in), hmac_sha512_vector1024_multiblock_out, sizeof(hmac_sha512_vector1024_multiblock_out), e); sha_finish: if (count != test_hmac_vector_num_calls) { res = PS_FAILURE; _psTrace("FAILED: some of the tests failed.\n"); } else { _psTraceInt("PASSED (%d vectors)\n", count); } test_hmac_vector_num_calls = 0; return res; } # ifdef USE_HMAC_SHA1 static int32 psHmacVectorTestsSHA1(void) { return psHmacVectorTestsShared(20); } # endif /* USE_HMAC_SHA1 */ # ifdef USE_HMAC_SHA256 static int32 psHmacVectorTestsSHA256(void) { return psHmacVectorTestsShared(32); } # endif /* USE_HMAC_SHA256 */ # ifdef USE_HMAC_SHA384 static int32 psHmacVectorTestsSHA384(void) { return psHmacVectorTestsShared(48); } # endif /* USE_HMAC_SHA384 */ # ifdef USE_HMAC_SHA1 static int32 psHmacVectorTestsSimultaneous(void) { psHmacSha1_t ctx1; psHmacSha1_t ctx2; psHmacSha1_t ctx3; int32 rv1; int32 rv2; int32 rv3; unsigned char md1[20]; unsigned char md2[20]; unsigned char md3[20]; rv1 = psHmacSha1Init(&ctx1, (unsigned char *) hmac_sha1_vector14_key, sizeof(hmac_sha1_vector14_key)); rv2 = psHmacSha1Init(&ctx2, (unsigned char *) hmac_sha1_vector16_key, sizeof(hmac_sha1_vector16_key)); rv3 = psHmacSha1Init(&ctx3, (unsigned char *) hmac_sha1_vector20_key, sizeof(hmac_sha1_vector20_key)); if (rv1 != PS_SUCCESS) { _psTrace("FAILED (hmac_sha1_vector14)\n"); } if (rv2 != PS_SUCCESS) { _psTrace("FAILED (hmac_sha1_vector16)\n"); } if (rv3 != PS_SUCCESS) { _psTrace("FAILED (hmac_sha1_vector20)\n"); } psHmacSha1Update(&ctx1, hmac_sha1_vector14_in, sizeof(hmac_sha1_vector14_in)); psHmacSha1Update(&ctx2, hmac_sha1_vector16_in, sizeof(hmac_sha1_vector16_in)); psHmacSha1Update(&ctx3, hmac_sha1_vector20_in, sizeof(hmac_sha1_vector20_in)); psHmacSha1Final(&ctx1, md1); psHmacSha1Final(&ctx2, md2); psHmacSha1Final(&ctx3, md3); if (Memcmp(md1, hmac_sha1_vector14_out, sizeof(hmac_sha1_vector14_out)) != 0) { _psTrace("FAILED (hmac_sha1_vector14)\n"); return PS_FAILURE; } if (Memcmp(md2, hmac_sha1_vector16_out, sizeof(hmac_sha1_vector16_out)) != 0) { _psTrace("FAILED (hmac_sha1_vector16)\n"); return PS_FAILURE; } if (Memcmp(md3, hmac_sha1_vector20_out, sizeof(hmac_sha1_vector20_out)) != 0) { _psTrace("FAILED (hmac_sha1_vector20)\n"); return PS_FAILURE; } _psTrace("PASSED\n"); return PS_SUCCESS; } # endif /* USE_HMAC_SHA1 */ static int32 psHmacVectorTests(void) { int32 res = PS_SUCCESS; # ifdef USE_HMAC_SHA1 res = psHmacVectorTestSimple(); # endif /* USE_HMAC_SHA1 */ _psTraceInt(" SHA-1 known vector test %d... ", 2); # ifdef USE_HMAC_SHA1 res |= psHmacVectorTestsSHA1(); # else _psTrace("SKIPPED.\n"); # endif /* USE_HMAC_SHA1 */ _psTraceInt(" SHA-256 known vector test %d... ", 1); # ifdef USE_HMAC_SHA256 res |= psHmacVectorTestsSHA256(); # else _psTrace("SKIPPED.\n"); # endif /* USE_HMAC_SHA256 */ _psTraceInt(" SHA-384 known vector test %d... ", 1); # ifdef USE_HMAC_SHA384 res |= psHmacVectorTestsSHA384(); # else _psTrace("SKIPPED.\n"); # endif /* USE_HMAC_SHA384 */ _psTrace(" Simultaneous hmac contexts... "); # ifdef USE_HMAC_SHA1 res |= psHmacVectorTestsSimultaneous(); # else _psTrace("SKIPPED.\n"); # endif /* USE_HMAC_SHA1 */ return res; } #endif /* USE_HMAC */ /******************************************************************************/ #ifdef USE_ECC # include "../../testkeys/EC/256_EC.h" # include "../../testkeys/EC/256_EC_KEY.h" # include "../../testkeys/EC/384_EC.h" # include "../../testkeys/EC/384_EC_KEY.h" # include "../../testkeys/EC/521_EC.h" # include "../../testkeys/EC/521_EC_KEY.h" static int32_t ecdh_kat(unsigned char *alice_priv, size_t alice_priv_len, unsigned char *bob_pub, size_t bob_pub_len, unsigned char *expected_secret, size_t expected_secret_len, int curve_id) { psPool_t *pool = NULL; psEccKey_t privkey = PS_ECC_STATIC_INIT; psEccKey_t pubkey_imported = PS_ECC_STATIC_INIT; const psEccCurve_t *curve; unsigned char got_secret[128] = { 0 }; int32_t rc; psSize_t secret_len; if (getEccParamById(curve_id, &curve) < 0) { return PS_FAIL; } rc = psEccParsePrivKey(pool, alice_priv, alice_priv_len, &privkey, curve); if (rc != PS_SUCCESS) { _psTrace("psEccParsePrivKey failed\n"); rc = PS_FAIL; goto L_FAIL; } rc = psEccX963ImportKey(pool, bob_pub, bob_pub_len, &pubkey_imported, curve); if (rc != PS_SUCCESS) { _psTrace("psEccX963ImportKey failed\n"); rc = PS_FAIL; goto L_FAIL; } secret_len = sizeof(got_secret); rc = psEccGenSharedSecret(pool, &privkey, &pubkey_imported, got_secret, &secret_len, NULL); if (rc != PS_SUCCESS) { _psTrace("psEccGenSharedSecret failed\n"); rc = PS_FAIL; goto L_FAIL; } if (secret_len != expected_secret_len) { _psTrace("Unexpected shared secret size\n"); rc = PS_FAIL; goto L_FAIL; } if (Memcmp(got_secret, expected_secret, secret_len)) { _psTrace("KAT failed\n"); rc = PS_FAIL; goto L_FAIL; } rc = PS_SUCCESS; _psTrace(" PASSED\n"); L_FAIL: psEccClearKey(&privkey); psEccClearKey(&pubkey_imported); return rc; } static int32_t ecdh_p256_kat(void) { int32_t rc; /* A prime256v1 keypair and an ECDH shared secret generated with it. */ unsigned char alice_priv[] = { 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x2a, 0x50, 0x32, 0x9a, 0xa5, 0x7e, 0x0d, 0xc0, 0x1f, 0xf9, 0xb1, 0xeb, 0xe4, 0x01, 0x4c, 0xc2, 0x87, 0x78, 0x91, 0xe3, 0xb6, 0x53, 0x59, 0x77, 0x3c, 0x0e, 0x3c, 0x15, 0xa3, 0xb5, 0x82, 0x96, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x42, 0x37, 0x6d, 0xf6, 0x3e, 0x06, 0x70, 0x7f, 0xa2, 0x36, 0x8d, 0x37, 0x90, 0x92, 0x93, 0xe5, 0xc3, 0x70, 0x94, 0x00, 0xd1, 0x09, 0xb2, 0xb5, 0x70, 0xa1, 0x82, 0xfe, 0xa6, 0xb0, 0xfc, 0xfa, 0x18, 0xea, 0x5e, 0xff, 0x87, 0x0f, 0xbf, 0xd5, 0xd6, 0x8b, 0x88, 0xb9, 0x1a, 0xcf, 0xf9, 0x53, 0xd2, 0xb0, 0x5c, 0x7b, 0x2f, 0x71, 0xf5, 0x95, 0xb0, 0xa1, 0x3d, 0xd6, 0xa5, 0x59, 0x14, 0x56 }; unsigned char bob_pub[] = { 0x04, 0x32, 0xee, 0xb1, 0x56, 0xf9, 0xb1, 0xc9, 0x80, 0x66, 0xa5, 0x7d, 0x94, 0xff, 0xde, 0x61, 0xbd, 0x3f, 0x2d, 0xf0, 0x1f, 0xc0, 0xb5, 0x1e, 0xc1, 0x05, 0x5b, 0x2b, 0xf9, 0x2a, 0x39, 0x6a, 0x94, 0x82, 0x6b, 0x77, 0xd4, 0xb9, 0x07, 0x02, 0xdb, 0x73, 0x6f, 0x95, 0xe9, 0xc3, 0xbd, 0xd5, 0x25, 0x5f, 0xea, 0x0b, 0xc4, 0xa6, 0x60, 0x83, 0x5c, 0xe4, 0x3a, 0xd9, 0x08, 0xf9, 0x9b, 0x09, 0x8c }; unsigned char secret[] = { 0xb1, 0xe2, 0x6c, 0x88, 0xe7, 0x06, 0x12, 0x1e, 0x92, 0x0f, 0xc2, 0x89, 0x35, 0x8d, 0x37, 0x36, 0x20, 0xfa, 0x81, 0x91, 0x53, 0x5d, 0x4c, 0xa1, 0x71, 0x1f, 0x8c, 0x90, 0xa4, 0x7f, 0x8b, 0xf4 }; _psTrace(" P-256 ECDH known-answer test..."); rc = ecdh_kat(alice_priv, sizeof(alice_priv), bob_pub, sizeof(bob_pub), secret, sizeof(secret), IANA_SECP256R1); if (rc == PS_FAIL) { _psTrace("P-256 ECDH known-answer test failed\n"); } return rc; } static int32_t ecdh_p384_kat(void) { int32_t rc; /* A secp384r1 keypair and an ECDH shared secret generated with it. */ unsigned char alice_priv[] = { 0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30, 0xfc, 0x80, 0x44, 0xc5, 0x86, 0xd4, 0x6a, 0x93, 0xa5, 0xd1, 0x33, 0xe0, 0x59, 0xe2, 0x5c, 0xca, 0x04, 0x89, 0xc6, 0x0e, 0x45, 0xcb, 0x5a, 0x3b, 0x22, 0x07, 0x6d, 0xcc, 0x1b, 0x49, 0xba, 0x80, 0xe9, 0x7f, 0x48, 0xb7, 0x7c, 0x9f, 0x49, 0x17, 0xa0, 0x41, 0x81, 0x5e, 0xc0, 0x75, 0x2a, 0x9b, 0xa0, 0x07, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0x6c, 0xc2, 0x05, 0x72, 0x70, 0x4b, 0x07, 0x2f, 0x36, 0x7c, 0x77, 0xa3, 0x04, 0xbe, 0x18, 0x56, 0x3f, 0xc9, 0xfa, 0x50, 0xe9, 0x2e, 0x0a, 0x24, 0x74, 0xa1, 0x0d, 0x48, 0x92, 0x71, 0x62, 0xb4, 0xd5, 0x69, 0xad, 0x8c, 0x31, 0xf0, 0xfe, 0xa5, 0x00, 0x6c, 0x1e, 0x34, 0x58, 0x1a, 0xd3, 0x83, 0x5a, 0x79, 0x81, 0xc9, 0xb5, 0x2b, 0x0f, 0x72, 0x6b, 0x5d, 0x20, 0x7b, 0xba, 0xd3, 0x4c, 0x93, 0xbb, 0xe4, 0x58, 0x46, 0x06, 0x92, 0xab, 0x5d, 0x30, 0xff, 0x03, 0xf6, 0xfe, 0x1c, 0x87, 0xfb, 0x5a, 0x00, 0xa5, 0x7e, 0x5e, 0xbd, 0x53, 0x02, 0x38, 0xe7, 0xf8, 0x53, 0x58, 0x19, 0x77, 0x2c }; unsigned char bob_pub[] = { 0x04, 0xba, 0x84, 0x0b, 0xd0, 0xab, 0xfd, 0x2f, 0x4c, 0x49, 0x19, 0x8c, 0xbf, 0x97, 0x55, 0x2d, 0xbc, 0x2d, 0x2a, 0xf0, 0x8b, 0x8f, 0xfc, 0x2b, 0x85, 0xdb, 0x02, 0x83, 0x9b, 0x41, 0xdd, 0x91, 0xda, 0xad, 0x1e, 0x43, 0x81, 0x18, 0xc9, 0xf7, 0xc2, 0x5a, 0x06, 0x05, 0xc5, 0x9b, 0x72, 0xf8, 0x5c, 0xf7, 0x25, 0xb3, 0x50, 0x98, 0x5e, 0x31, 0xa0, 0x24, 0x0f, 0xc4, 0x9a, 0x2f, 0xc9, 0x6d, 0x4e, 0x2a, 0xab, 0xdb, 0x9e, 0xa1, 0x73, 0x36, 0x5b, 0x3f, 0x39, 0xcf, 0x5f, 0x45, 0x0f, 0xa5, 0xc8, 0xfc, 0x40, 0x57, 0xaf, 0x96, 0x0d, 0x25, 0xd6, 0x7e, 0x0b, 0xe1, 0x6a, 0x4d, 0x09, 0x08, 0xca }; unsigned char secret[] = { 0x1b, 0x74, 0x01, 0x47, 0x86, 0x9a, 0x79, 0x25, 0x43, 0x2a, 0x39, 0x3f, 0xe5, 0x8c, 0x7c, 0xb6, 0x9b, 0xd3, 0x19, 0xb0, 0x3d, 0xc2, 0xa2, 0xb0, 0x6a, 0xca, 0x33, 0x66, 0x82, 0xb2, 0x47, 0x84, 0x1e, 0xe8, 0x71, 0xeb, 0x68, 0x88, 0xfa, 0xfd, 0x08, 0x52, 0xe3, 0x2e, 0x04, 0x59, 0xe7, 0xe7 }; _psTrace(" P-384 ECDH known-answer test..."); rc = ecdh_kat(alice_priv, sizeof(alice_priv), bob_pub, sizeof(bob_pub), secret, sizeof(secret), IANA_SECP384R1); if (rc == PS_FAIL) { _psTrace("P-384 ECDH known-answer test failed\n"); return rc; } return PS_SUCCESS; } # ifdef USE_SECP521R1 static int32_t ecdh_p521_kat(void) { int32_t rc; /* A secp521r1 keypair and an ECDH shared secret generated with it. */ unsigned char alice_priv[] = { 0x30, 0x81, 0xdc, 0x02, 0x01, 0x01, 0x04, 0x42, 0x00, 0x0e, 0x21, 0x99, 0x99, 0x28, 0xe5, 0x42, 0x2f, 0x6b, 0xbc, 0x7a, 0xb5, 0x50, 0xe4, 0x6a, 0xbd, 0xdc, 0x5e, 0x90, 0xb0, 0x5c, 0xd3, 0x19, 0x9b, 0xee, 0xc4, 0xab, 0x66, 0x5a, 0x02, 0xba, 0x65, 0xce, 0xf6, 0xb1, 0x32, 0xa9, 0xca, 0x1c, 0x42, 0x02, 0x99, 0xda, 0xf7, 0xae, 0x3c, 0x12, 0x14, 0x59, 0x73, 0xf1, 0x28, 0xef, 0x17, 0xd4, 0xc5, 0xd9, 0xa9, 0xec, 0x77, 0x74, 0x3c, 0x0a, 0x3a, 0x46, 0xa0, 0x07, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 0xa1, 0x81, 0x89, 0x03, 0x81, 0x86, 0x00, 0x04, 0x01, 0x1a, 0x21, 0x9b, 0x8c, 0x59, 0x86, 0x25, 0x5f, 0xb3, 0x52, 0xd3, 0xa6, 0xaf, 0x06, 0x06, 0x1e, 0x3c, 0x89, 0x0d, 0x5d, 0xf4, 0xb9, 0x92, 0xd5, 0x1b, 0xe4, 0xa5, 0x20, 0x9d, 0xd6, 0x3d, 0x01, 0x80, 0xee, 0x4b, 0xd4, 0xea, 0x0a, 0xe6, 0xd3, 0x4e, 0xfa, 0xe9, 0x7f, 0xf9, 0xf9, 0x94, 0x65, 0x0e, 0x85, 0x54, 0xdd, 0xc7, 0xfe, 0xae, 0x97, 0xd1, 0x6a, 0xd3, 0x7b, 0x90, 0x1f, 0x50, 0xcc, 0x6a, 0x01, 0x88, 0x18, 0x09, 0x27, 0x83, 0x70, 0x28, 0xe4, 0x05, 0x88, 0x03, 0xe9, 0x1b, 0x0b, 0x93, 0x5a, 0x3b, 0xba, 0x2d, 0x91, 0xff, 0x20, 0x6f, 0xb4, 0x86, 0x91, 0x30, 0xdb, 0xf0, 0xa3, 0x08, 0xb0, 0x23, 0x61, 0xa8, 0x80, 0x91, 0x53, 0x64, 0x93, 0x9a, 0x3c, 0xca, 0x50, 0x18, 0x04, 0xb4, 0x9c, 0x78, 0xae, 0x48, 0xd6, 0x01, 0x51, 0x30, 0xd2, 0xcd, 0x7c, 0x59, 0xdc, 0xfe, 0x20, 0x7c, 0xa7, 0x88 }; unsigned char bob_pub[] = { 0x04, 0x01, 0xb4, 0xb3, 0x6a, 0x53, 0x35, 0x45, 0xbc, 0x72, 0xb7, 0x1c, 0x34, 0x72, 0xb2, 0x24, 0x84, 0xb7, 0xe7, 0x1e, 0x67, 0x86, 0x8c, 0x2d, 0xf8, 0x51, 0xb7, 0xe4, 0x06, 0xa5, 0x94, 0x8a, 0xfe, 0x27, 0xea, 0x82, 0xd9, 0x14, 0x08, 0x73, 0xd7, 0xae, 0x16, 0xbf, 0x06, 0x4f, 0x3c, 0xf1, 0x74, 0x60, 0x5e, 0x6e, 0xa2, 0xcc, 0x68, 0x67, 0xc0, 0x48, 0x50, 0xd2, 0xfe, 0x24, 0x7d, 0xe4, 0x8e, 0x4b, 0xb6, 0x00, 0xce, 0x3a, 0xad, 0xdb, 0x73, 0xb0, 0x39, 0x20, 0x6b, 0x19, 0x24, 0x33, 0x3f, 0x7a, 0xd8, 0xb5, 0x59, 0x0a, 0x3a, 0x59, 0xc4, 0x49, 0xa3, 0x90, 0x6d, 0xc2, 0xa0, 0xf8, 0x0d, 0xee, 0xd5, 0x00, 0x6b, 0x13, 0xb1, 0x08, 0x83, 0x7b, 0x3b, 0xda, 0x16, 0x0f, 0x6b, 0x4c, 0x5e, 0xdb, 0xda, 0x94, 0xc7, 0x6c, 0xbc, 0xa3, 0x2e, 0x13, 0xe2, 0xcf, 0x6a, 0xa2, 0x57, 0x46, 0x10, 0xd2, 0xab, 0x94, 0x80 }; unsigned char secret[] = { 0x00, 0x26, 0x96, 0xe5, 0x2b, 0xe4, 0x56, 0xac, 0x90, 0x0e, 0x5f, 0x9e, 0x49, 0xf2, 0xd0, 0x19, 0x48, 0xa2, 0xf1, 0x2e, 0xe8, 0x1a, 0x47, 0x5c, 0x30, 0xc7, 0x83, 0x59, 0xd4, 0x60, 0x55, 0x28, 0x95, 0x99, 0xa0, 0x65, 0xc1, 0xeb, 0x8d, 0x92, 0x75, 0x63, 0x55, 0xa7, 0x4d, 0xe8, 0xb1, 0xe5, 0x96, 0x50, 0x24, 0x45, 0x8f, 0x3d, 0xd2, 0x69, 0xb7, 0xca, 0xd3, 0x15, 0x5a, 0xf6, 0x5c, 0x20, 0x5f, 0x49 }; _psTrace(" P-521 ECDH known-answer test..."); rc = ecdh_kat(alice_priv, sizeof(alice_priv), bob_pub, sizeof(bob_pub), secret, sizeof(secret), IANA_SECP521R1); if (rc == PS_FAIL) { _psTrace("P-521 ECDH known-answer test failed\n"); return rc; } return PS_SUCCESS; } # endif /* USE_SECP521R1 */ static int32_t psEccPairwiseTest(void) { psPool_t *pool = NULL; psEccKey_t k1 = PS_ECC_STATIC_INIT; psEccKey_t k1_imported = PS_ECC_STATIC_INIT; psEccKey_t k2 = PS_ECC_STATIC_INIT; psEccKey_t k2_imported = PS_ECC_STATIC_INIT; psEccKey_t priv = PS_ECC_STATIC_INIT; unsigned char k1_exported[256]; unsigned char k2_exported[256]; psSize_t k1len = sizeof(k1_exported); psSize_t k2len = sizeof(k2_exported); const psEccCurve_t *curve; unsigned char sk1k2[128], sk2k1[128]; unsigned char in[128], out[128]; psSize_t secretlen, inlen, outlen; int32_t status, rc = PS_FAIL; # ifdef USE_CERT_PARSE psX509Cert_t *cert = NULL; # endif /* USE_CERT_PARSE */ if (getEccParamById(IANA_SECP256R1, &curve) < 0) { goto L_FAIL; } _psTraceStr(" %s Key Exchange...", curve->name); if (psEccGenKey(pool, &k1, curve, NULL) < 0) { goto L_FAIL; } if (psEccGenKey(pool, &k2, curve, NULL) < 0) { _psTrace("GenKey failed."); goto L_FAIL; } if (psEccX963ExportKey(pool, &k1, k1_exported, &k1len) < 0) { _psTrace("psEccX963ExportKey 1 failed."); goto L_FAIL; } if (psEccX963ExportKey(pool, &k2, k2_exported, &k2len) < 0) { _psTrace("psEccX963ExportKey 2 failed."); goto L_FAIL; } if (psEccX963ImportKey(pool, k1_exported, k1len, &k1_imported, curve) < 0) { _psTrace("psEccX963ImportKey 1 failed."); goto L_FAIL; } if (psEccX963ImportKey(pool, k2_exported, k2len, &k2_imported, curve) < 0) { _psTrace("psEccX963ImportKey 2 failed."); goto L_FAIL; } secretlen = sizeof(sk1k2); if (psEccGenSharedSecret(pool, &k1, &k2_imported, sk1k2, &secretlen, NULL) < 0 || secretlen != curve->size) { _psTrace("GenSharedSecret K1 failed."); goto L_FAIL; } secretlen = sizeof(sk2k1); if (psEccGenSharedSecret(pool, &k2, &k1_imported, sk2k1, &secretlen, NULL) < 0 || secretlen != curve->size) { _psTrace("GenSharedSecret K2 failed."); goto L_FAIL; } if (memcmpct(sk1k2, sk2k1, curve->size) != 0) { _psTrace("Shared secret doesn't match."); #ifdef DEBUG_ALGORITHM_TEST psTraceBytes("K1K2 Secret", sk1k2, secretlen); psTraceBytes("K2K1 Secret", sk2k1, secretlen); #endif goto L_FAIL; } _psTrace(" PASSED\n"); _psTraceStr(" %s Signature Validation...", curve->name); /* Generate some random bytes to sign */ if (psGetEntropy(in, curve->size, NULL) < 0) { _psTrace("GetEntropy failed."); goto L_FAIL; } inlen = secretlen; /* Sign and verify with generated key 1*/ outlen = sizeof(out); if (psEccDsaSign(pool, &k1, in, inlen, out, &outlen, 0, NULL) < 0) { _psTrace("Sign K1 failed."); goto L_FAIL; } if (psEccDsaVerify(pool, &k1_imported, in, inlen, out, outlen, &status, NULL) < 0 || status != 1) { _psTrace("K1 signature didn't validate."); goto L_FAIL; } /* Sign and verify with generated key 2, asking for a length prefix for TLS */ outlen = sizeof(out); if (psEccDsaSign(pool, &k2, in, inlen, out, &outlen, 1, NULL) < 0) { _psTrace("Sign K2 failed."); goto L_FAIL; } /* Skip the first 2 bytes of length, as they are not the signature */ if (psEccDsaVerify(pool, &k2_imported, in, inlen, out + 2, outlen - 2, &status, NULL) < 0 || status != 1) { _psTrace("K2 signature didn't validate."); goto L_FAIL; } /* Sign and verify with private key from header and corresponding public key in certificate, or with the private key if not parsing certs. */ if (psEccParsePrivKey(pool, EC256KEY, sizeof(EC256KEY), &priv, curve) < 0) { _psTrace("ParsePrivKey failed."); goto L_FAIL; } # ifdef USE_CERT_PARSE if (psX509ParseCert(pool, EC256, sizeof(EC256), &cert, 0) < 0) { _psTrace("ParseCert failed."); goto L_FAIL; } # endif outlen = sizeof(out); if (psEccDsaSign(pool, &priv, in, inlen, out, &outlen, 1, NULL) < 0) { _psTrace("Sign header key failed."); goto L_FAIL; } if (psEccDsaVerify(pool, # ifdef USE_CERT_PARSE &cert->publicKey.key.ecc, # else &priv, # endif in, inlen, out + 2, outlen - 2, &status, NULL) < 0 || status != 1) { _psTrace("Header key signature didn't validate."); goto L_FAIL; } rc = PS_SUCCESS; _psTrace(" PASSED\n"); L_FAIL: memzero_s(in, sizeof(in)); memzero_s(out, sizeof(out)); memzero_s(sk1k2, sizeof(sk1k2)); memzero_s(sk2k1, sizeof(sk2k1)); psEccClearKey(&k1); psEccClearKey(&k1_imported); psEccClearKey(&k2); psEccClearKey(&k2_imported); psEccClearKey(&priv); # ifdef USE_CERT_PARSE if (cert) { psX509FreeCert(cert); } # endif return rc; } static int32_t psEccTestParsePriv(void) { psPool_t *pool = NULL; psEccKey_t *key1; psEccKey_t key2, key3; int32_t rc; /*************************************************************/ _psTrace(" P-256 psEccNewKey + psEccParsePrivKey..."); rc = psEccNewKey(pool, &key1, NULL); if (rc != PS_SUCCESS) { goto fail; } rc = psEccParsePrivKey(pool, EC256KEY, sizeof(EC256KEY), key1, NULL); if (rc != PS_SUCCESS) { psEccDeleteKey(&key1); goto fail; } psEccDeleteKey(&key1); _psTrace(" PASSED\n"); /*************************************************************/ _psTrace(" P-256 psEccInitKey + psEccParsePrivKey..."); rc = psEccInitKey(pool, &key2, NULL); if (rc != PS_SUCCESS) { goto fail; } rc = psEccParsePrivKey(pool, EC256KEY, sizeof(EC256KEY), &key2, NULL); if (rc != PS_SUCCESS) { goto fail; } psEccClearKey(&key2); _psTrace(" PASSED\n"); /*************************************************************/ _psTrace(" P-256 uninitialized key + psEccParsePrivKey..."); rc = psEccParsePrivKey(pool, EC256KEY, sizeof(EC256KEY), &key3, NULL); if (rc != PS_SUCCESS) { goto fail; } psEccClearKey(&key3); _psTrace(" PASSED\n"); return PS_SUCCESS; fail: _psTrace(" FAILED\n"); return rc; } static int32_t psEccTestSigVer() { int32_t rc = PS_FAILURE; psPubKey_t key_noparam, key_noparam_nopub; /* This is testkeys/EC/256_EC_KEY.noparam.pem in DER form. */ unsigned char p256_key_noparam[] = { 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x5c, 0xe9, 0x89, 0xc5, 0xb1, 0x53, 0xa0, 0x02, 0x3c, 0x90, 0xbe, 0x3a, 0x2a, 0x73, 0xb2, 0x08, 0x16, 0xc3, 0xed, 0xbc, 0xd5, 0xd6, 0x67, 0x26, 0x10, 0x4e, 0xec, 0x79, 0x28, 0x0f, 0xbf, 0xcb, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x5f, 0xad, 0x62, 0x02, 0x42, 0x48, 0xba, 0xfb, 0xe2, 0x88, 0xd8, 0x7f, 0xb9, 0x72, 0xcb, 0x28, 0xae, 0xc3, 0x8a, 0x1e, 0xc3, 0x0e, 0x9c, 0x7d, 0x7a, 0xa4, 0xb5, 0x7f, 0xda, 0xbd, 0x46, 0x5a, 0xb9, 0x95, 0x39, 0xe0, 0x44, 0x51, 0x71, 0xba, 0xe3, 0xb3, 0x40, 0xf2, 0x54, 0xfd, 0x23, 0x84, 0xb2, 0xea, 0x2a, 0x84, 0xa3, 0x4f, 0xd7, 0xb0, 0x08, 0xba, 0x6e, 0x80, 0xc3, 0xeb, 0xdf, 0x2f }; /* This is testkeys/EC/256_EC_KEY.noparam.nopub.pem in DER form. */ unsigned char p256_key_noparam_nopub[] = { 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0x5c, 0xe9, 0x89, 0xc5, 0xb1, 0x53, 0xa0, 0x02, 0x3c, 0x90, 0xbe, 0x3a, 0x2a, 0x73, 0xb2, 0x08, 0x16, 0xc3, 0xed, 0xbc, 0xd5, 0xd6, 0x67, 0x26, 0x10, 0x4e, 0xec, 0x79, 0x28, 0x0f, 0xbf, 0xcb, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }; unsigned char tbs[] = {'i', 'n', 's', 'i', 'd', 'e'}; unsigned char tbs_hash[64] = {0}; psSize_t tbs_hash_len = sizeof(tbs_hash); unsigned char sig[150] = {0}; psSize_t sig_len = sizeof(sig); int32 verifyResult = 0; /* This is a simple pairwise sign + verify test. But in addition, it tests that signing is possible without a public key: key_noparam and key_noparam_nopub contain the same private key, but key_noparam_nopub omits the optional public key. */ _psTrace(" P-256 sig ver test..."); rc = psParseUnknownPrivKeyMem(NULL, p256_key_noparam, sizeof(p256_key_noparam), NULL, &key_noparam); if (rc < 0) { _psTrace("psParseUnknownPrivKeyMem failed\n"); rc = PS_FAILURE; goto out_no_key_1; } rc = psParseUnknownPrivKeyMem(NULL, p256_key_noparam_nopub, sizeof(p256_key_noparam_nopub), NULL, &key_noparam_nopub); if (rc < 0) { _psTrace("psParseUnknownPrivKeyMem failed\n"); rc = PS_FAILURE; goto out_no_key_2; } rc = psComputeHashForSig(tbs, sizeof(tbs), OID_SHA256_ECDSA_SIG, tbs_hash, &tbs_hash_len); if (rc != PS_SUCCESS) { _psTraceInt("psComputeHashForSig failed: %d\n", rc); rc = PS_FAILURE; goto out; } rc = psEccDsaSign(NULL, &key_noparam_nopub.key.ecc, tbs_hash, tbs_hash_len, sig, &sig_len, 0, NULL); if (rc != PS_SUCCESS) { _psTraceInt("psEccDsaSign failed : %d\n", rc); rc = PS_FAILURE; goto out; } rc = psEccDsaVerify(NULL, &key_noparam.key.ecc, tbs_hash, tbs_hash_len, sig, sig_len, &verifyResult, NULL); if (rc != PS_SUCCESS) { _psTraceInt("psEccDsaVerify failed : %d\n", rc); rc = PS_FAILURE; goto out; } if (verifyResult != 1) { _psTrace("verification failed failed\n"); rc = PS_FAILURE; goto out; } out: psEccClearKey(&key_noparam_nopub.key.ecc); out_no_key_2: psEccClearKey(&key_noparam.key.ecc); out_no_key_1: if (rc == PS_SUCCESS) { _psTrace(" PASSED\n"); } else { _psTrace(" FAILED\n"); } return rc; } static int32_t psEccTest(void) { int32_t rc; rc = ecdh_p256_kat(); if (rc != PS_SUCCESS) { return rc; } rc = ecdh_p384_kat(); if (rc != PS_SUCCESS) { return rc; } # ifdef USE_SECP521R1 rc = ecdh_p521_kat(); if (rc != PS_SUCCESS) { return rc; } # endif /* USE_SECP521R1 */ rc = psEccPairwiseTest(); if (rc != PS_SUCCESS) { return rc; } rc = psEccTestParsePriv(); if (rc != PS_SUCCESS) { return rc; } rc = psEccTestSigVer(); if (rc != PS_SUCCESS) { return rc; } return PS_SUCCESS; } #endif /* USE_ECC */ /******************************************************************************/ #if defined(USE_X25519) static int32 psDhX25519Test(void) { psRes_t rv; const unsigned char alice_priv_key[PS_DH_X25519_PRIVATE_KEY_BYTES] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a }; const unsigned char alice_pub_key[PS_DH_X25519_PUBLIC_KEY_BYTES] = { 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a }; const unsigned char bob_priv_key[PS_DH_X25519_PRIVATE_KEY_BYTES] = { 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb }; const unsigned char bob_pub_key[PS_DH_X25519_PUBLIC_KEY_BYTES] = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f }; const unsigned char shared[PS_DH_X25519_SHARED_SECRET_BYTES] = { 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e, 0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42 }; const unsigned char v9[PS_DH_X25519_PUBLIC_KEY_BYTES] = { 9, /* 0, ... */ }; unsigned char alice_new_priv_key[PS_DH_X25519_PRIVATE_KEY_BYTES]; unsigned char alice_new_pub_key[PS_DH_X25519_PUBLIC_KEY_BYTES]; unsigned char alice_old_pub_key[PS_DH_X25519_PUBLIC_KEY_BYTES]; unsigned char bob_new_priv_key[PS_DH_X25519_PRIVATE_KEY_BYTES]; unsigned char bob_new_pub_key[PS_DH_X25519_PUBLIC_KEY_BYTES]; unsigned char shared_alice[PS_DH_X25519_SHARED_SECRET_BYTES]; unsigned char shared_bob[PS_DH_X25519_SHARED_SECRET_BYTES]; /* Use RFC 7748 6.1. test vector as KAT. */ _psTrace(" DH X25519 KAT (RFC 7748 6.1)..."); rv = psDhX25519GenSharedSecret(bob_pub_key, alice_priv_key, shared_alice); if (rv == PS_DISABLED_FEATURE_FAIL) { _psTrace(" SKIPPED (X25519 not available)\n"); goto next_test; } FAIL_IF(rv != PS_SUCCESS); rv = psDhX25519GenSharedSecret(alice_pub_key, bob_priv_key, shared_bob); FAIL_IF(rv != PS_SUCCESS); FAIL_IF(memcmp(shared, shared_alice, PS_DH_X25519_SHARED_SECRET_BYTES) != 0); FAIL_IF(memcmp(shared, shared_bob, PS_DH_X25519_SHARED_SECRET_BYTES) != 0); rv = psDhX25519GenSharedSecret(v9, alice_priv_key, alice_old_pub_key); FAIL_IF(rv != PS_SUCCESS); FAIL_IF(memcmp(alice_pub_key, alice_old_pub_key, PS_DH_X25519_PUBLIC_KEY_BYTES) != 0); _psTrace(" PASSED\n"); next_test: /* Ephemeral key agreement: new keys and secrets. */ _psTrace(" DH X25519 Ephemeral Key Agreement (pair-wise test)..."); rv = psDhX25519GenKey(alice_new_priv_key, alice_new_pub_key); if (rv == PS_DISABLED_FEATURE_FAIL) { _psTrace(" SKIPPED (X25519 not available)\n"); goto dh_x25519_not_avail; } FAIL_IF(rv != PS_SUCCESS); rv = psDhX25519GenKey(bob_new_priv_key, bob_new_pub_key); FAIL_IF(rv != PS_SUCCESS); rv = psDhX25519GenSharedSecret(bob_new_pub_key, alice_new_priv_key, shared_alice); FAIL_IF(rv != PS_SUCCESS); rv = psDhX25519GenSharedSecret(alice_new_pub_key, bob_new_priv_key, shared_bob); FAIL_IF(rv != PS_SUCCESS); FAIL_IF(memcmp(shared_bob, shared_alice, PS_DH_X25519_SHARED_SECRET_BYTES) != 0); _psTrace(" PASSED\n"); dh_x25519_not_avail: return 0; } #endif /* USE_X25519 */ #ifdef USE_ED25519 static int32 psEd25519Test(void) { /* Test vector 1 from RFC 8032 */ unsigned char privKey1[] = { 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60 }; unsigned char pubKey1[] = { 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a }; /* message1 is empty */ unsigned char expected_sig1[] = { 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, 0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b }; /* Test vector 2 from RFC 8032 */ unsigned char privKey2[] = { 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f, 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb }; unsigned char pubKey2[] = { 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc, 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c }; unsigned char message2[] = { 0x72 }; unsigned char expected_sig2[] = { 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40, 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, 0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00 }; /* Pairwise test with the keypair from test vector 2 and a random message. */ unsigned char tbs3[] = { 0x09, 0xfc, 0xad, 0x40, 0x52, 0xf5, 0xd1, 0x6b, 0x42, 0x14, 0x96, 0xe2, 0x7e, 0xb5, 0x4b, 0xae, 0x46, 0x54, 0xce, 0xff, 0x9d, 0x26, 0x04, 0xb7, 0x1c, 0x10, 0xd1, 0x59, 0xfb, 0x02, 0xcd, 0xab, 0x4e, 0x93, 0x6c, 0x10, 0x54, 0x54, 0xc8, 0xfa, 0x57, 0xe9, 0x15, 0xcd, 0x41, 0xdf, 0x5b, 0x69, 0x8b, 0x26, 0x54, 0x31, 0xaf, 0xe2, 0x6e, 0x8e, 0xf2, 0x73, 0x76, 0xc6, 0x77, 0xaa, 0x3f, 0x93, 0x03, 0x9c, 0x83, 0x1a, 0x1f, 0xaf, 0xd4, 0x59, 0x2a, 0x20, 0x27, 0xac, 0x76, 0xe8, 0x96, 0x5f, 0xfe, 0xa0, 0xde, 0x69, 0xa4, 0xb5, 0x26, 0x26, 0x1d, 0x06, 0x13, 0xe0, 0x48, 0xe8, 0xf0, 0x6c, 0xae, 0x6b, 0x67, 0xf3, 0xa8, 0x3a, 0x66, 0xed, 0xec, 0x4c, 0xbe, 0x51, 0xbe, 0x93, 0x2f, 0x04, 0xd0, 0x3e, 0xf2, 0x22, 0xee, 0x35, 0x03, 0x4e, }; unsigned char privKey4[] = { 0xd8, 0xe9, 0x76, 0xb2, 0x3f, 0x1f, 0xf7, 0x88, 0x75, 0xf5, 0xdd, 0xf8, 0x7a, 0xc6, 0x49, 0x30, 0x6e, 0xe9, 0x9f, 0xcb, 0x9d, 0x1e, 0x2b, 0xc0, 0x18, 0xef, 0xbb, 0x75, 0x89, 0xe6, 0x77, 0x67 }; unsigned char pubKey4[] = { 0x1a, 0x30, 0x88, 0x18, 0x47, 0x2f, 0x97, 0xda, 0x04, 0xf4, 0xa4, 0xe3, 0xbd, 0x6c, 0x0c, 0x16, 0xb9, 0x48, 0xc1, 0xd1, 0x42, 0xd7, 0x8e, 0x92, 0x84, 0xa0, 0x74, 0x2a, 0x43, 0x9e, 0x0e, 0x29 }; /* Another test key pair. */ unsigned char privKey5[] = { 0x30, 0x52, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0xd8, 0xe9, 0x76, 0xb2, 0x3f, 0x1f, 0xf7, 0x88, 0x75, 0xf5, 0xdd, 0xf8, 0x7a, 0xc6, 0x49, 0x30, 0x6e, 0xe9, 0x9f, 0xcb, 0x9d, 0x1e, 0x2b, 0xc0, 0x18, 0xef, 0xbb, 0x75, 0x89, 0xe6, 0x77, 0x67, 0xa1, 0x22, 0x04, 0x20, 0x1a, 0x30, 0x88, 0x18, 0x47, 0x2f, 0x97, 0xda, 0x04, 0xf4, 0xa4, 0xe3, 0xbd, 0x6c, 0x0c, 0x16, 0xb9, 0x48, 0xc1, 0xd1, 0x42, 0xd7, 0x8e, 0x92, 0x84, 0xa0, 0x74, 0x2a, 0x43, 0x9e, 0x0e, 0x29 }; unsigned char privKey5Bytes[] = { 0xd8, 0xe9, 0x76, 0xb2, 0x3f, 0x1f, 0xf7, 0x88, 0x75, 0xf5, 0xdd, 0xf8, 0x7a, 0xc6, 0x49, 0x30, 0x6e, 0xe9, 0x9f, 0xcb, 0x9d, 0x1e, 0x2b, 0xc0, 0x18, 0xef, 0xbb, 0x75, 0x89, 0xe6, 0x77, 0x67 }; unsigned char pubKey5[] = { 0x1a, 0x30, 0x88, 0x18, 0x47, 0x2f, 0x97, 0xda, 0x04, 0xf4, 0xa4, 0xe3, 0xbd, 0x6c, 0x0c, 0x16, 0xb9, 0x48, 0xc1, 0xd1, 0x42, 0xd7, 0x8e, 0x92, 0x84, 0xa0, 0x74, 0x2a, 0x43, 0x9e, 0x0e, 0x29 }; unsigned char tbs5[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x81, 0xe0, 0xfe, 0xde, 0xee, 0xce, 0xbe, 0xa4, 0x43, 0xa0, 0xc2, 0x51, 0x8f, 0x0b, 0x9b, 0xe4, 0x61, 0x68, 0xea, 0xc7, 0x9c, 0x8a, 0x1c, 0xb3, 0x6e, 0x49, 0xfe, 0xf9, 0x51, 0xbe, 0x95, 0x58 }; /* This is the first example private key in section 7 in draft-ietf-curdle-pkix-08. It is of type OneAsymmetricKey. */ unsigned char myPrivKeyBuf[] = { 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0xd4, 0xee, 0x72, 0xdb, 0xf9, 0x13, 0x58, 0x4a, 0xd5, 0xb6, 0xd8, 0xf1, 0xf7, 0x69, 0xf8, 0xad, 0x3a, 0xfe, 0x7c, 0x28, 0xcb, 0xf1, 0xd4, 0xfb, 0xe0, 0x97, 0xa8, 0x8f, 0x44, 0x75, 0x58, 0x42 }; unsigned char myPrivKeyBytes[] = { /* 0x04, 0x20, */ 0xd4, 0xee, 0x72, 0xdb, 0xf9, 0x13, 0x58, 0x4a, 0xd5, 0xb6, 0xd8, 0xf1, 0xf7, 0x69, 0xf8, 0xad, 0x3a, 0xfe, 0x7c, 0x28, 0xcb, 0xf1, 0xd4, 0xfb, 0xe0, 0x97, 0xa8, 0x8f, 0x44, 0x75, 0x58, 0x42 }; /* This is the second example private key from section 7 in the above mentioned draft. Includes a pub key and the params.*/ unsigned char myPrivKeyBuf2[] = { 0x30, 0x72, 0x02, 0x01, 0x01, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0xd4, 0xee, 0x72, 0xdb, 0xf9, 0x13, 0x58, 0x4a, 0xd5, 0xb6, 0xd8, 0xf1, 0xf7, 0x69, 0xf8, 0xad, 0x3a, 0xfe, 0x7c, 0x28, 0xcb, 0xf1, 0xd4, 0xfb, 0xe0, 0x97, 0xa8, 0x8f, 0x44, 0x75, 0x58, 0x42, 0xa0, 0x1f, 0x30, 0x1d, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x09, 0x14, 0x31, 0x0f, 0x0c, 0x0d, 0x43, 0x75, 0x72, 0x64, 0x6c, 0x65, 0x20, 0x43, 0x68, 0x61, 0x69, 0x72, 0x73, 0x81, 0x21, 0x00, 0x19, 0xbf, 0x44, 0x09, 0x69, 0x84, 0xcd, 0xfe, 0x85, 0x41, 0xba, 0xc1, 0x67, 0xdc, 0x3b, 0x96, 0xc8, 0x50, 0x86, 0xaa, 0x30, 0xb6, 0xb6, 0xcb, 0x0c, 0x5c, 0x38, 0xad, 0x70, 0x31, 0x66, 0xe1 }; unsigned char sig[512] = {0}; unsigned char *vlSig; psSizeL_t sigLen; psSize_t sigLenPsSize; int32_t rc; psPubKey_t myPrivKey; psCurve25519Key_t myEd25519PrivKey; psBool_t verifyResult; _psTrace(" Ed25519 signature KAT (RFC 8032, test vector 1)..."); rc = psEd25519Sign(NULL, 0, sig, &sigLen, privKey1, pubKey1); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != sizeof(expected_sig1)); FAIL_IF(Memcmp(sig, expected_sig1, sigLen)); _psTrace(" PASSED\n"); _psTrace(" Ed25519 verification (RFC 8032, test vector 1)..."); rc = psEd25519Verify(sig, NULL, 0, pubKey1); FAIL_IF(rc != PS_SUCCESS); _psTrace(" PASSED\n"); _psTrace(" Ed25519 signature KAT (RFC 8032, test vector 2)..."); rc = psEd25519Sign(message2, sizeof(message2), sig, &sigLen, privKey2, pubKey2); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != sizeof(expected_sig2)); FAIL_IF(Memcmp(sig, expected_sig2, sigLen)); _psTrace(" PASSED\n"); _psTrace(" Ed25519 verification (RFC 8032, test vector 2)..."); rc = psEd25519Verify(sig, message2, sizeof(message2), pubKey2); FAIL_IF(rc != PS_SUCCESS); _psTrace(" PASSED\n"); _psTrace(" Ed25519 pairwise test..."); rc = psEd25519Sign(tbs3, sizeof(tbs3), sig, &sigLen, privKey2, pubKey2); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != 64); rc = psEd25519Verify(sig, tbs3, sizeof(tbs3), pubKey2); FAIL_IF(rc != PS_SUCCESS); _psTrace(" PASSED\n"); _psTrace(" Ed25519 pairwise test 2..."); rc = psEd25519Sign(tbs3, sizeof(tbs3), sig, &sigLen, privKey4, pubKey4); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != 64); rc = psEd25519Verify(sig, tbs3, sizeof(tbs3), pubKey4); FAIL_IF(rc != PS_SUCCESS); _psTrace(" PASSED\n"); _psTrace(" Ed25519 private key parsing (psEd25519ParsePrivKey)..."); rc = psEd25519ParsePrivKey(NULL, myPrivKeyBuf, sizeof(myPrivKeyBuf), &myEd25519PrivKey); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(Memcmp(myEd25519PrivKey.priv, myPrivKeyBytes, 32)); _psTrace(" PASSED\n"); _psTrace(" Ed25519 private key parsing (incl. pubkey and params)..."); rc = psParseUnknownPrivKeyMem(NULL, myPrivKeyBuf2, sizeof(myPrivKeyBuf2), NULL, &myPrivKey); FAIL_IF(rc != PS_ED25519); FAIL_IF(myPrivKey.type != PS_ED25519); _psTrace(" PASSED\n"); _psTrace(" Ed25519 pairwise test with psSign and psVerify..."); rc = psSign(NULL, &myPrivKey, OID_ED25519_KEY_ALG, tbs5, sizeof(tbs5), &vlSig, &sigLenPsSize, NULL); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLenPsSize != 64); rc = psVerify(NULL, tbs5, sizeof(tbs5), vlSig, sigLenPsSize, &myPrivKey, OID_ED25519_KEY_ALG, &verifyResult, NULL); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(verifyResult != PS_TRUE); psFree(vlSig, NULL); _psTrace(" PASSED\n"); _psTrace(" Ed25519 key parse + pairwise test..."); rc = psEd25519ParsePrivKey(NULL, privKey5, sizeof(privKey5), &myEd25519PrivKey); FAIL_IF(rc != PS_SUCCESS); Memcpy(myEd25519PrivKey.pub, pubKey5, sizeof(pubKey5)); rc = psEd25519Sign(tbs5, sizeof(tbs5), sig, &sigLen, myEd25519PrivKey.priv, myEd25519PrivKey.pub); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != 64); rc = psEd25519Verify(sig, tbs5, sizeof(tbs5), myEd25519PrivKey.pub); FAIL_IF(rc != PS_SUCCESS); Memcpy(myEd25519PrivKey.priv, privKey5Bytes, sizeof(privKey5Bytes)); rc = psEd25519Sign(tbs5, sizeof(tbs5), sig, &sigLen, myEd25519PrivKey.priv, myEd25519PrivKey.pub); FAIL_IF(rc != PS_SUCCESS); FAIL_IF(sigLen != 64); rc = psEd25519Verify(sig, tbs5, sizeof(tbs5), myEd25519PrivKey.pub); FAIL_IF(rc != PS_SUCCESS); _psTrace(" PASSED\n"); return PS_SUCCESS; } #endif /* USE_ED25519 */ # include "osdep_unistd.h" # include "osdep_stdio.h" # if defined(USE_RSA) || defined(USE_ECC) # ifdef MATRIX_USE_FILE_SYSTEM # ifdef USE_PRIVATE_KEY_PARSING int32 loadKeyPair(psPool_t *pool, psPubKey_t *keyPair, const char *key_filename) { int32 keytype; keytype = psParseUnknownPrivKey(pool, 1, (char *) key_filename, NULL, keyPair); if (keytype < 0) { Printf("psParseUnknownPrivKey failed\n"); return PS_FAILURE; } return PS_SUCCESS; } int32 loadKeyPub(psPool_t *pool, psPubKey_t *keyPub, const char *key_filename) { int32 keytype; keytype = psParseUnknownPubKey(pool, 1, (char *) key_filename, NULL, keyPub); if (keytype < 0) { /* Alternative path. In current software either function should work. */ psPool_t *pool = NULL; psRes_t rc; unsigned char *buf; psSizeL_t len; Printf("(INFORMATIVE: psParseUnknownPubKey failed: " "psParseUnknownPubKeyMem used instead)"); rc = psGetFileBuf(pool, key_filename, &buf, &len); if (rc != PS_SUCCESS) { return PS_FAILURE; } rc = (psRes_t) psParseUnknownPubKeyMem(pool, buf, (int32) len, NULL, keyPub); psFree(buf, pool); if (rc != PS_SUCCESS) { /* Successful key loading. */ return PS_FAILURE; } keytype = 2; } if (keytype != 2) { Printf("psParseUnknownPubKey(Mem): unexpected key type.\n"); return PS_FAILURE; } return PS_SUCCESS; } # endif /* USE_PRIVATE_KEY_PARSING */ # endif /* MATRIX_USE_FILE_SYSTEM */ # endif /* USE_RSA || USE_ECC */ # ifdef USE_ECC # ifdef USE_PEM_DECODE static int32_t psEccLoadPub_helper(void) { FILE *file = NULL; const char *public_key_filename = "testkeys/EC/256_EC_PUB.pem"; const char *private_key_filename = "testkeys/EC/256_EC_KEY.pem"; unsigned char testdata1[] = { 'a', 'b', 'c', 'd' }; unsigned char testdata2[] = { 'a', 'b', 'c', 'D' }; unsigned char sigbuf[128]; psPubKey_t public, private; int32 rc; psRes_t res; psRes_t res1a; psRes_t res1b; psRes_t res2a; psRes_t res2b; psSize_t siglen = sizeof sigbuf; psBool_t verify1a = PS_FALSE; psBool_t verify2a = PS_FALSE; psBool_t verify1b = PS_FALSE; psBool_t verify2b = PS_FALSE; unsigned char hashOut[SHA512_HASH_SIZE]; psSize_t hashOutLen = PS_SIZEOF(hashOut); /* Note: this part of the test is dependent on path. */ for (;; ) { char cwd_from_buf[512]; char cwd_to_buf[512]; char *cwd_from = NULL; char *cwd_to = NULL; file = Fopen(public_key_filename, "r"); if (file) { break; } cwd_from = getcwd(cwd_from_buf, sizeof(cwd_from_buf)); if (cwd_from == NULL) { Printf("psEccLoadPub cannot locate current directory\n"); return PS_FAILURE; } if (chdir("..") != 0) { Printf("psEccLoadPub cannot locate test key files\n"); return PS_FAILURE; } cwd_to = getcwd(cwd_to_buf, sizeof(cwd_to_buf)); if (cwd_to == NULL) { Printf("psEccLoadPub cannot locate current directory\n"); return PS_FAILURE; } /* If directory did not change, i.e. we are in root */ if (Strcmp(cwd_to, cwd_from) == 0) { Printf("psEccLoadPub cannot locate %s\n", public_key_filename); return PS_FAILURE; } } Fclose(file); Memset(&private, 0, sizeof private); rc = loadKeyPair(MATRIX_NO_POOL, &private, private_key_filename); if (rc != PS_SUCCESS) { Printf("Failed to load Ecc private key %s\n", private_key_filename); return PS_FAILURE; } Memset(&public, 0, sizeof public); rc = loadKeyPub(MATRIX_NO_POOL, &public, public_key_filename); if (rc != PS_SUCCESS) { Printf("Failed to load Ecc private key %s\n", public_key_filename); return PS_FAILURE; } /* Pairwise testing procedure: create signature and verify it against proper data and improper data. Do this twice: with public key of key pair and with separate public key. */ res = psComputeHashForSig(testdata1, PS_SIZEOF32(testdata1), OID_SHA256_ECDSA_SIG, hashOut, &hashOutLen); if (res != PS_SUCCESS) { Printf("Hash SHA-256 computation failed\n"); return PS_FAILURE; } res = psEccDsaSign(MATRIX_NO_POOL, &private.key.ecc, hashOut, hashOutLen, sigbuf, &siglen, 0, NULL); if (res != PS_SUCCESS) { Printf("ECC signature operation with NIST P-256 failed\n"); return PS_FAILURE; } res1a = psHashDataAndVerifySig(MATRIX_NO_POOL, testdata1, PS_SIZEOF32(testdata1), sigbuf, siglen, &private, OID_SHA256_ECDSA_SIG, &verify1a, NULL); res2a = psHashDataAndVerifySig(MATRIX_NO_POOL, testdata2, PS_SIZEOF32(testdata2), sigbuf, siglen, &private, OID_SHA256_ECDSA_SIG, &verify2a, NULL); if (res1a != PS_SUCCESS || (res2a != PS_FAILURE && res2a != PS_VERIFICATION_FAILED) || verify1a != PS_TRUE || verify2a != PS_FALSE) { Printf("Verify results unexpected (got %d %d %d %d)\n", (int) res1a, (int) res2a, (int) verify1a, (int) verify2a); return PS_FAILURE; } res1b = psHashDataAndVerifySig(MATRIX_NO_POOL, testdata1, PS_SIZEOF32(testdata1), sigbuf, siglen, &public, OID_SHA256_ECDSA_SIG, &verify1b, NULL); res2b = psHashDataAndVerifySig(MATRIX_NO_POOL, testdata2, PS_SIZEOF32(testdata2), sigbuf, siglen, &public, OID_SHA256_ECDSA_SIG, &verify2b, NULL); if (res1b != PS_SUCCESS || (res2b != PS_FAILURE && res2b != PS_VERIFICATION_FAILED) || verify1b != PS_TRUE || verify2b != PS_FALSE) { Printf("Verify results separate pk unexpected (got %d %d %d %d)\n", (int) res1b, (int) res2b, (int) verify1b, (int) verify2b); return PS_FAILURE; } psClearPubKey(&public); psClearPubKey(&private); return PS_SUCCESS; } static int32_t psEccLoadPub(void) { int32_t rc; _psTrace(" ECC key loading and usage test... "); rc = psEccLoadPub_helper(); if (rc == PS_SUCCESS) { _psTrace(" SUCCESS\n"); } else { _psTrace("FAILURE\n"); } return rc; } # endif /* USE_PEM_DECODE */ # endif /* USE_ECC */ /******************************************************************************/ typedef struct { int32 (*fn)(void); char name[64]; } test_t; static test_t tests[] = { #ifdef USE_AES # ifdef USE_AES_BLOCK { psAesTestBlock, "***** AES BLOCK TESTS *****" }, # endif # ifdef USE_AES_CBC { psAesTestCBC, "***** AES-CBC TESTS *****" }, # endif # ifdef USE_AES_GCM { psAesTestGCM, "***** AES-GCM TESTS *****" }, { psAesTestGCM2, "***** AES-GCM TESTS 2 *****" }, # endif # ifdef USE_AES_WRAP { psAesTestWrap, "***** AES WRAP TEST *****" }, # endif # ifdef USE_AES_CMAC { psAesTestCmac, "***** AES CMAC TEST *****" }, # endif # ifdef USE_AES_CTR { psAesTestCTR, "***** AES-CTR TESTS *****" }, # endif #else { NULL, "AES" }, #endif #ifdef USE_CHACHA20_POLY1305_IETF { psChacha20Poly1305IetfTest, "***** CHACHA20_POLY1305 TESTS *****" }, #endif #ifdef USE_PKCS5 { psPBKDF2, "***** PBKDF2 TESTS *****" }, #endif #ifdef USE_3DES { psDes3Test #else { NULL #endif , "***** 3DES TESTS *****" }, #ifdef USE_SEED { psSeedTest #else { NULL #endif , "***** SEED TESTS *****" }, #ifdef USE_ARC4 { psArc4Test #else { NULL #endif , "***** RC4 TESTS *****" }, #ifdef USE_IDEA { psIdeaTest #else { NULL #endif , "***** IDEA TESTS *****" }, #ifdef USE_SHA1 { psSha1Test #else { NULL #endif , "***** SHA1 TESTS *****" }, #ifdef USE_SHA224 { psSha224Test #else { NULL #endif , "***** SHA224 TESTS *****" }, #ifdef USE_SHA256 { psSha256Test #else { NULL #endif , "***** SHA256 TESTS *****" }, #ifdef USE_SHA384 { psSha384Test #else { NULL #endif , "***** SHA384 TESTS *****" }, #ifdef USE_SHA512 { psSha512Test #else { NULL #endif , "***** SHA512 TESTS *****" }, #ifdef USE_MD5 { psMd5Test #else { NULL #endif , "***** MD5 TESTS *****" }, #ifdef USE_MD5SHA1 { psMd5Sha1Test #else { NULL #endif , "***** MD5SHA1 TESTS *****" }, #ifdef USE_MD4 { psMd4Test #else { NULL #endif , "***** MD4 TESTS *****" }, #ifdef USE_MD2 { psMd2Test #else { NULL #endif , "***** MD2 TESTS *****" }, #ifdef USE_HMAC { psHmacVectorTests #else { NULL #endif , "***** HMAC TESTS *****" }, { psPrngTests , "***** PRNG TESTS *****" }, #if defined(USE_RSA) && defined(USE_PRIVATE_KEY_PARSING) { psRsaEncryptTest #else { NULL #endif , "***** RSA ENCRYPT TESTS *****" }, #if defined(USE_RSA) && defined(USE_PRIVATE_KEY_PARSING) { psRsaSignTest #else { NULL #endif , "***** RSA SIGN TESTS *****" }, #if defined(USE_RSA) && defined(USE_PEM_DECODE) { psRsaKeyFormatTests #else { NULL #endif , "***** RSA KEY FORMAT TESTS *****" }, #if defined(USE_PKCS1_OAEP) && !defined(USE_HARDWARE_CRYPTO_PKA) { psRsaOaepVectorTest #else { NULL #endif , "***** RSA RSAES_OAEP TESTS *****" }, #if defined(USE_PKCS1_PSS) && defined(USE_SHA1) && !defined(USE_CL_RSA) && !defined(USE_HARDWARE_CRYPTO_PKA) { psRsaPssVectorTest #else { NULL #endif , "***** RSA RSASSA_PSS TESTS *****" }, #ifdef USE_ECC { psEccTest #else { NULL #endif , "***** ECC TESTS *****" }, #if defined(USE_ECC) && defined(USE_PEM_DECODE) { psEccLoadPub #else { NULL #endif /* USE_ECC && USE_PEM_DECODE */ , "***** ECC LOAD PUBLIC KEY TEST *****" }, { NULL , "***** PRF TESTS *****" }, { NULL , "***** PRF2 TESTS *****" }, #ifdef USE_HKDF { psHkdfTests #else { NULL #endif , "***** HKDF TESTS *****" }, #ifdef USE_HKDF { psHkdfExpandLabelTests #else { NULL #endif , "***** HKDF-EXPAND-LABEL TESTS *****" }, #ifdef USE_X25519 { psDhX25519Test, "***** DH X25519 TESTS *****" }, #else { NULL, "***** DH X25519 TESTS *****" }, #endif /* USE_X25519 */ #ifdef USE_ED25519 { psEd25519Test, "***** Ed25519 TESTS *****" }, #else { NULL, "***** Ed25519 TESTS *****" }, #endif /* USE_X25519 */ { NULL, "" } }; /******************************************************************************/ /* Main */ int main(int argc, char **argv) { int32 i; int l; int32_t num_fail = 0; int32_t num_succ = 0; int32_t num_test = 0; int32_t rc; if (argc > 1) { if (!Strcmp(argv[1], "--list")) { Printf("Tests:\n"); for (i = 0; *tests[i].name; i++) { Printf("%s\n", tests[i].name); } return 0; } for(l = 1; l < argc; l++) { for (i = 0; *tests[i].name; i++) { if (Strstr(tests[i].name, argv[l])) { break; } } if (!*tests[i].name) { Fprintf(stderr, "Test not found: %s\n", argv[l]); Fprintf(stderr, "Usage: %s [--list | test...]\n", argv[0]); exit(1); } } } if (psCryptoOpen(PSCRYPTO_CONFIG) < PS_SUCCESS) { _psTrace("Failed to initialize library: psCryptoOpen failed\n"); return -1; } for (i = 0; *tests[i].name; i++) { for(l = 1; argc > 1 && l < argc; l++) { if (Strstr(tests[i].name, argv[l])) { break; } } if (l == argc && argc > 1) { continue; } if (tests[i].fn) { _psTraceStr("%s\n", tests[i].name); rc = tests[i].fn(); if (rc == PS_SUCCESS) { num_succ++; } else { num_fail++; } num_test++; } else { _psTraceStr("%s: SKIPPED\n", tests[i].name); } } Printf("Finishing...\n"); psCryptoClose(); _psTraceInt(" %d failures", num_fail); _psTraceInt(" in %d tests\n", num_test); #ifdef WIN32 _psTrace("Press any key to close"); getchar(); #endif if (num_fail == 0) { _psTrace("All OK!\n"); return 0; } return EXIT_FAILURE; }