/* Copyright (c) (2012,2013,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved. * * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which * is contained in the License.txt file distributed with corecrypto) and only to * people who accept that license. IMPORTANT: Any license rights granted to you by * Apple Inc. (if any) are limited to internal use within your organization only on * devices and computers you own or control, for the sole purpose of verifying the * security characteristics and correct functioning of the Apple Software. You may * not, directly or indirectly, redistribute the Apple Software or any portions thereof. */ #include "testmore.h" #include "testbyteBuffer.h" #include "testccnBuffer.h" // static int verbose = 1; #if (CCRSA == 0) entryPoint(ccrsa_tests,"ccrsa") #else #include "ccrsa_internal.h" #include #include #include #include #include #include "crypto_test_rsa.h" #include "crypto_test_rsapss.h" #include "crypto_test_rsapkcs1v15.h" #define RSA_KNOWN_KEY_STRESS 10 static int check_sane_keysize(ccrsa_full_ctx_t fk, int public) { size_t keySize; ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); if (public) { keySize = ccrsa_pubkeylength(pubk); } else { keySize = ccrsa_privkeylength(fk); } return (keySize < 512 || keySize > 4097); } static int crypt_decrypt(ccrsa_full_ctx_t fk) { ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); cc_size n = ccrsa_ctx_n(fk); cc_unit data[n], cipher[n], decrypted[n]; ccn_clear(n, data); ccn_clear(n, cipher); ccn_clear(n, decrypted); is(ccn_random_bits(ccrsa_pubkeylength(pubk)-1, data, global_test_rng),0,"Random data"); is(ccrsa_pub_crypt(pubk, cipher, data),0,"Pub crypt"); is(ccrsa_priv_crypt_blinded(global_test_rng, fk, decrypted, cipher),0,"Priv crypt"); return !ok_memcmp(decrypted, data, ccn_sizeof_n(n), "Results are what we started with"); } static int oaep_decrypt_error_test(ccrsa_full_ctx_t fk) { ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); size_t keySizeBits = ccrsa_pubkeylength(pubk); size_t keySizeBytes = (keySizeBits+7)/8; cc_size n=ccrsa_ctx_n(pubk); cc_unit tmp_u[n]; ccn_clear(n, tmp_u); uint8_t tmp[keySizeBytes]; int status = 0,expected_status; uint32_t test_status = 0; int test_index=0; bool run_test=true; struct ccrng_sequence_state rng_seq; // Arbitrary choices for the test struct ccdigest_info di_big = { .output_size = keySizeBytes/2+1, }; const struct ccdigest_info *di_test; const struct ccdigest_info *di=NULL; if (keySizeBytes<128) { di=ccsha1_di(); } else { di=ccsha256_di(); } cc_assert(2*di->output_size+2output_size+2); // Message of maximum size uint8_t M[M_len]; uint8_t seed[di->output_size]; uint8_t seed_mask[di->output_size]; size_t maskedDB_len=keySizeBytes-di->output_size-1; memset(seed,0xff,sizeof(seed)); byteBuffer decryptedData = mallocByteBuffer(M_len); char* test_description=NULL; // Message is all 0 memset(M,0,M_len); // Seed is all 0xFF memset(seed,0xff,sizeof(seed)); // dbMask = MGF(seed, k - hLen - 1) uint8_t dbMask[maskedDB_len]; ccmgf(di, sizeof(dbMask), dbMask, sizeof(seed), seed); // Helpers for operating on the encoded message. uint8_t *ptr = ccrsa_block_start(keySizeBytes, tmp_u, 0); // n might be larger than required by the modulus. ptr += ccn_sizeof_n(n - ccn_nof_size(keySizeBytes)); uint8_t *maskedDB = &ptr[1 + di->output_size]; while(run_test) { di_test = di; keySizeBytes = (keySizeBits+7)/8; M_len = decryptedData->len = sizeof(M); // The 2nd and 5th test need zero-bytes in the padding. if (test_index == 1 || test_index == 4) { M_len -= 7; } // Encode message, in little endian as an array of cc_unit ccrng_sequence_init(&rng_seq, sizeof(seed), seed); status=ccrsa_oaep_encode(di, (struct ccrng_state*)&rng_seq, keySizeBytes, tmp_u, M_len, M); cc_assert(status==0); (void) status; // Analyzer warning in release mode switch (test_index) { case 0: test_description="oaep_decrypt: Sanity"; // Keep the encoded message good for sanity expected_status=CCERR_OK; // Pass break; case 1: test_description="oaep_decrypt: Sanity #2"; // Keep the encoded message good for sanity expected_status=CCERR_OK; // Pass break; case 2: test_description="oaep_decrypt: Y not zero"; // Y is not zero ccn_swap(n, tmp_u); cc_assert(ptr[0] == 0); ptr[0] = 0x01; ccn_swap(n, tmp_u); if (keySizeBits % 8 == 1) { // We need the encoded message to be less than the modulus. // Otherwise, ccrsa_pub_crypt will return an error. // By tampering with the message to set the high byte to one, // we risk violating that constraint iff the high byte of the // modulus is also one (i.e. its bit-length is one mod eight). // We reduce by the modulus to avoid unexpected failures. // If the modular reduction is actually performed (i.e. tmp_u > m), // this results in a free pass for this test case. We do not // expect to receive this pass often enough for regressions // to go unnoticed. ccn_mod(n, tmp_u, n, tmp_u, n, ccrsa_ctx_m(fk)); } expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 3: test_description="oaep_decrypt: No Separator"; // No separator 0x01 ccn_swap(n, tmp_u); cc_assert((maskedDB[maskedDB_len - M_len - 1] ^ dbMask[maskedDB_len - M_len - 1]) == 0x01); maskedDB[maskedDB_len - M_len - 1] ^= 0x01; ccmgf(di, di->output_size, seed_mask, maskedDB_len, maskedDB); // Recompute seed mask cc_xor(di->output_size, &ptr[1], seed, seed_mask); // Overwrite maskedSeed ccn_swap(n, tmp_u); expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 4: test_description="oaep_decrypt: Padding is not zero"; // Padding is not zero ccn_swap(n, tmp_u); cc_assert((maskedDB[maskedDB_len - M_len - 1] ^ dbMask[maskedDB_len - M_len - 1]) == 0x01); cc_assert((maskedDB[maskedDB_len - M_len - 2] ^ dbMask[maskedDB_len - M_len - 2]) == 0x00); maskedDB[maskedDB_len - M_len - 2] ^= 0x02; ccmgf(di, di->output_size, seed_mask, maskedDB_len, maskedDB); // Recompute seed mask cc_xor(di->output_size, &ptr[1], seed, seed_mask); // Overwrite maskedSeed ccn_swap(n, tmp_u); expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 5: test_description="oaep_decrypt: lHash does not match"; // lHash does not match ccn_swap(n, tmp_u); maskedDB[0] ^= 0x01; ccmgf(di, di->output_size, seed_mask, maskedDB_len, maskedDB); // Recompute seed mask cc_xor(di->output_size, &ptr[1], seed, seed_mask); // Overwrite maskedSeed ccn_swap(n, tmp_u); expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 6: test_description="oaep_decrypt: maskedSeed does not match"; // maskedSeed corrupted ccn_swap(n, tmp_u); ptr[2] ^= 0x01; ccn_swap(n, tmp_u); expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 7: test_description="oaep_decrypt: key vs hash length error"; // Padding test fails di_test = &di_big; expected_status=CCRSA_INVALID_CONFIG; break; case 8: test_description="oaep_decrypt: output is too small"; // Output buffer is too small decryptedData->len=keySizeBytes-2*di->output_size-3; expected_status=CCRSA_INVALID_INPUT; break; case 9: test_description="oaep_decrypt: ciphertext is too small"; // Ciphertext is too small keySizeBytes -= 1; expected_status=CCRSA_INVALID_INPUT; break; default: run_test=false; expected_status=1; break; } if (run_test) { // Encrypt is(ccrsa_pub_crypt(pubk, tmp_u, tmp_u),0, "Test %i: ccrsa_pub_crypt",test_index); // we need to write leading zeroes if necessary, truncate for test 8 ccn_write_uint_padded(n, tmp_u, keySizeBytes, tmp); // Try to decrypt, expected to fail ok((status = ccrsa_decrypt_oaep_blinded(global_test_rng, fk,di_test, &decryptedData->len, decryptedData->bytes, keySizeBytes, tmp, 0, NULL)) == expected_status, "Test %i: %s",test_index,test_description); // Check return value if (status==expected_status) // Expect failures { test_status|=(1< must fail tmp[1]=0x02; // Prefix byte 2 memset(&tmp[2],0xff,keySizeBytes-2); tmp[10]=0x00; // Prefix separator expected_status=CCRSA_PRIVATE_OP_ERROR; // Fail break; case 2: test_description="pkcs1v15_decrypt: Padding second byte"; // Handcraft message tmp[0]=0x00; // Prefix byte 1 tmp[1]=0xff; // Prefix byte 2: Not 0x02 => must fail memset(&tmp[2],0xff,keySizeBytes-2); tmp[10]=0x00; // Prefix separator expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 3: test_description="pkcs1v15_decrypt: No separator"; // Handcraft message tmp[0]=0x00; // Prefix byte 1 tmp[1]=0x02; // Prefix byte 2 memset(&tmp[2],0xff,keySizeBytes-2); // No separator => must fail expected_status=CCRSA_PRIVATE_OP_ERROR; break; case 4: test_description="pkcs1v15_decrypt: Padding length"; // Handcraft message tmp[0]=0x00; // Prefix byte 1 tmp[1]=0x02; // Prefix byte 2 memset(&tmp[2],0xff,keySizeBytes-2); tmp[9]=0x00; // Prefix separator expected_status=CCRSA_PRIVATE_OP_ERROR; break; default: run_test=false; expected_status=1; break; } if (run_test) { // Convert tmp to unsigned big number representation for encryption ccn_zero(n, tmp_u); ccn_read_uint(n,tmp_u,keySizeBytes,tmp); if (ccn_cmp(n,tmp_u,ccrsa_ctx_m(fk))<0) { // Encrypt is(ccrsa_pub_crypt(pubk, tmp_u, tmp_u),0,"ccrsa_pub_crypt"); /* we need to write leading zeroes if necessary */ ok(ccn_write_uint_padded_ct(n, tmp_u, keySizeBytes, tmp)>=0,"serializing"); // Try to decrypt, expected to fail decryptedData->len=keySizeBytes; ok((status = ccrsa_decrypt_eme_pkcs1v15_blinded(global_test_rng, fk, &decryptedData->len, decryptedData->bytes, keySizeBytes, tmp)) == expected_status, test_description); } else { // In rare cases, the erroneous message (tmp) can not be encrypted: // For example, when tmp is constructed with MSB of 0x01 (eg. "0x0102FFF...") and // the key's most significant byte is also 0x01, there is a probability for modulus <= tmp // (for example if the input key's second byte is 0x00 or 0x01). // In this case tmp is not valid to encrypt for the given key. // When that occurs, we skip this test. status=expected_status; pass("ccrsa_pub_crypt"); pass(test_description); } if (status==expected_status) // Expect failures { test_status|=(1<len, plaintextData->bytes); is(status,0,"rng error"); encryptedData = mallocByteBuffer(keySizeBytes); expected_status=0; break; case 1: test_description="pkcs1v15_encrypt: output buffer too short"; plaintextData = mallocByteBuffer(keySizeBytes-11); status = ccrng_generate(global_test_rng, plaintextData->len, plaintextData->bytes); is(status,0,"rng error"); encryptedData = mallocByteBuffer(keySizeBytes-1); expected_status=CCRSA_INVALID_INPUT; break; case 2: test_description="pkcs1v15_encrypt: message too long"; plaintextData = mallocByteBuffer(keySizeBytes-10); status = ccrng_generate(global_test_rng, plaintextData->len, plaintextData->bytes); is(status,0,"rng error"); encryptedData = mallocByteBuffer(keySizeBytes); expected_status=CCRSA_INVALID_INPUT; break; default: run_test=false; expected_status=1; break; } if (run_test) { // Encrypt the message output_len=encryptedData->len; ok((status = ccrsa_encrypt_eme_pkcs1v15(pubk, global_test_rng, &output_len, encryptedData->bytes, plaintextData->len, plaintextData->bytes )) == expected_status, test_description); free(encryptedData);encryptedData=NULL; free(plaintextData);plaintextData=NULL; // Keep record of failures if (status==expected_status) // Expect failures { test_status|=(1<len, encryptedKey->bytes, sizeof(keydata), keydata)) == 0, "Wrap Key Data with RSA Encryption"); if(status) goto errout; ok((status = ccrsa_decrypt_eme_pkcs1v15_blinded(rng, fk, &decryptedKey->len, decryptedKey->bytes, encryptedKey->len, encryptedKey->bytes)) == 0, "Unwrap Key Data with RSA Encryption"); if(status) goto errout; } break; case PADDING_OAEP: { ok((status = ccrsa_encrypt_oaep(pubk, ccsha1_di(), rng, &encryptedKey->len, encryptedKey->bytes, sizeof(keydata), keydata, 0, NULL)) == 0, "Wrap Key Data with RSA Encryption"); if(status) goto errout; ok((status = ccrsa_decrypt_oaep_blinded(rng,fk, ccsha1_di(), &decryptedKey->len, decryptedKey->bytes, encryptedKey->len, encryptedKey->bytes, 0, NULL)) == 0, "Unwrap Key Data with RSA Encryption"); if(status) goto errout; } break; } status=!ok_memcmp(keydata,decryptedKey->bytes,sizeof(keydata),"Round Trip wrap/unwrap"); errout: free(encryptedKey); free(decryptedKey); return status; } #define MAXKEYSPACE 512 static int sign_verify(ccrsa_full_ctx_t fk, int padding, struct ccrng_state *rng, const struct ccdigest_info *di) { int status = 1; bool valid=false; byteBuffer signature = mallocByteBuffer(MAXKEYSPACE*2); uint8_t random_msg[di->output_size]; uint8_t hash[di->output_size]; ok_status(ccrng_generate(global_test_rng, sizeof(random_msg), random_msg), "Get some random for msg"); ccdigest(di, di->output_size, random_msg, hash); ccrsa_pub_ctx_t pk = ccrsa_ctx_public(fk); switch(padding) { case PADDING_PKCS1: { ok_status_or_goto(ccrsa_sign_pkcs1v15_blinded(global_test_rng, fk, di->oid, sizeof(hash), hash, &signature->len, signature->bytes), "RSA PKCS v1.5 Signing", errout); ok_status_or_goto(ccrsa_verify_pkcs1v15(pk, di->oid, sizeof(hash), hash, signature->len, signature->bytes, &valid), "RSA PKCS v1.5 Verifying", errout); ok_status_or_goto(ccrsa_sign_pkcs1v15_msg(fk, di, sizeof(random_msg), random_msg, &signature->len, signature->bytes), "ccrsa_sign_pkcs1v15_msg failure", errout); ok_status_or_goto(ccrsa_verify_pkcs1v15(pk, di->oid, sizeof(hash), hash, signature->len, signature->bytes, &valid), "ccrsa_verify_pkcs1v15 failure", errout); } break; case PADDING_PKCS1_NO_OID: { size_t pub_key_bytesize=CC_BITLEN_TO_BYTELEN(ccrsa_pubkeylength(ccrsa_ctx_public(fk))); size_t hash_size=1+(size_t)cc_rand((unsigned)pub_key_bytesize-12); uint8_t hash_nullOID[hash_size]; uint8_t fault_canary[sizeof(CCRSA_PKCS1_FAULT_CANARY)]; ok_status(ccrng_generate(global_test_rng, hash_size, hash_nullOID), "Get some random for hash"); ok_status_or_goto(ccrsa_sign_pkcs1v15_blinded(global_test_rng, fk, NULL, hash_size, hash_nullOID, &signature->len, signature->bytes), "RSA PKCS v1.5 Signing with null OID", errout); ok_status_or_goto(ccrsa_verify_pkcs1v15(pk, NULL, hash_size, hash_nullOID, signature->len, signature->bytes, &valid), "RSA PKCS v1.5 Verifying with null OID", errout); if(!valid) { cc_printf("hash_nullOID, modSize %zu, hashSize %zu\n",pub_key_bytesize,hash_size); cc_print("hash",hash_size,hash_nullOID); goto errout; } is_or_goto(ccrsa_verify_pkcs1v15_digest(pk, NULL, hash_size, hash_nullOID, signature->len, signature->bytes, fault_canary), CCERR_VALID_SIGNATURE, "ccrsa_verify_pkcs1v15_digest failure null OID", errout); ok_memcmp_or_goto(CCRSA_PKCS1_FAULT_CANARY, fault_canary, sizeof(CCRSA_PKCS1_FAULT_CANARY), errout, "ccrsa_verify_pkcs1v15_digest buffers differs"); } break; case PADDING_PSS: { size_t salt_len=sizeof(hash); ok_status_or_goto(ccrsa_sign_pss_blinded(rng,fk, di, di, salt_len, rng, sizeof(hash), hash, &signature->len, signature->bytes), "RSA Signing", errout); ok_status_or_goto(ccrsa_verify_pss(pk, di, di, sizeof(hash), hash, signature->len, signature->bytes, salt_len, &valid), "RSA Verifying", errout); ok_status_or_goto(ccrsa_sign_pss_msg(fk, di, di, salt_len, rng, sizeof(random_msg), random_msg, &signature->len, signature->bytes), "ccrsa_sign_pss_msg failure", errout); ok_status_or_goto(status = ccrsa_verify_pss(pk, di, di, sizeof(hash), hash, signature->len, signature->bytes, salt_len, &valid), "RSA Verifying", errout); } break; default: { fail("Unknown padding mode"); } break; } ok(valid == true, "Signature verifies"); if(!valid) goto errout; return 0; errout: free(signature); return -1; } static int export_import(ccrsa_full_ctx_t fk) { int pubkeytest = 1; int privkeytest = 1; int status = 0; byteBuffer tmp=NULL; if(pubkeytest) { ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); ccrsa_full_ctx_decl(ccn_sizeof(ccrsa_privkeylength(fk)), tmpkey); ccrsa_pub_ctx_t pubk2 = ccrsa_ctx_public(tmpkey); tmp = mallocByteBuffer(ccrsa_export_pub_size(pubk)); // Public key test ok_or_goto((status = ccrsa_export_pub(pubk, tmp->len, tmp->bytes)) == 0, "Exported Public Key",export_import_exit); ok_or_goto((ccrsa_ctx_n(pubk2) = ccrsa_import_pub_n(tmp->len, tmp->bytes)) != 0, "Got Key N",export_import_exit); ok_or_goto((status = ccrsa_import_pub(pubk2, tmp->len, tmp->bytes)) == 0, "Imported Public Key",export_import_exit); ok_or_goto((status = check_sane_keysize(tmpkey, 1)) == 0, "Keysize is realistic",export_import_exit); free(tmp);tmp=NULL; } if(privkeytest) { ccrsa_full_ctx_decl(ccn_sizeof(ccrsa_privkeylength(fk)), key2); tmp = mallocByteBuffer(ccrsa_export_priv_size(fk)); // Private key test ok_or_goto((status = ccrsa_export_priv(fk, tmp->len, tmp->bytes)) == 0, "Exported Private Key",export_import_exit); ok_or_goto((ccrsa_ctx_n(key2) = ccrsa_import_priv_n(tmp->len, tmp->bytes)) != 0, "Got Key N",export_import_exit); ok_or_goto((status = ccrsa_import_priv(key2, tmp->len, tmp->bytes)) == 0, "Imported Private Key",export_import_exit); ok_or_goto((status = check_sane_keysize(key2, 0)) == 0, "Keysize is realistic",export_import_exit); ok_or_goto((status = crypt_decrypt(key2)) == 0, "Can round-trip re-imported key",export_import_exit); free(tmp);tmp=NULL; } export_import_exit: free(tmp); if (status==0) { return 0; // No error } return 1; // Error; } //============================================================================== // Keys //============================================================================== // Private-Key(2048 bit) (Big Endian, with leading zeros) const uint8_t key_0_modulus[]={ 0x00, 0x92, 0xe4, 0xa7, 0xd3, 0x2a, 0x34, 0xe1, 0x5d, 0xcb, 0x9e, 0x82, 0x21, 0x27, 0x52, 0x25, 0x25, 0xf8, 0xba, 0xeb, 0x5f, 0xa0, 0xf3, 0xe5, 0xd8, 0x82, 0xdf, 0x84, 0x51, 0x03, 0x2a, 0x0f, 0x23, 0x4e, 0x5f, 0xd9, 0x9b, 0x95, 0x50, 0x05, 0xbc, 0xc3, 0x8b, 0xd8, 0xbe, 0xe4, 0x58, 0x5e, 0x4e, 0x06, 0x10, 0x0b, 0x0a, 0x80, 0x7a, 0x08, 0x46, 0xff, 0x8e, 0xd7, 0xf2, 0x61, 0x6e, 0x60, 0xba, 0x9d, 0x17, 0x35, 0x30, 0x4e, 0x4f, 0xdd, 0xb0, 0xc7, 0xe4, 0xa2, 0x72, 0xf1, 0x3b, 0xb2, 0xe9, 0x5f, 0x37, 0x32, 0x43, 0xa7, 0xe6, 0x1f, 0xf5, 0x7a, 0xab, 0x44, 0x09, 0x1a, 0x06, 0xa0, 0x6b, 0x53, 0x0d, 0x42, 0x4b, 0x7a, 0xf2, 0xa4, 0x5a, 0x21, 0x24, 0x29, 0xe3, 0x25, 0xb9, 0xee, 0x20, 0x65, 0x11, 0x60, 0x6a, 0x66, 0x07, 0xea, 0x66, 0x71, 0x24, 0x7d, 0x73, 0xc8, 0x2b, 0x56, 0x3b, 0x8e, 0x68, 0x19, 0xe7, 0xfb, 0x00, 0x88, 0xa7, 0x7a, 0xfb, 0xb9, 0x5b, 0x56, 0xbe, 0x0d, 0xe9, 0x0c, 0x23, 0x59, 0x43, 0x36, 0xff, 0x7d, 0xc6, 0x94, 0xe9, 0x58, 0x4f, 0x81, 0x03, 0x15, 0x22, 0xba, 0x36, 0x30, 0x33, 0x6c, 0x5c, 0x5a, 0xca, 0xdc, 0x2d, 0x51, 0xe0, 0x05, 0x86, 0x0c, 0xec, 0x28, 0x68, 0x29, 0xd7, 0xba, 0x82, 0xbc, 0xf6, 0xec, 0x02, 0x55, 0x3b, 0x9d, 0xc9, 0x22, 0xac, 0x0f, 0x26, 0x0f, 0xcb, 0xb0, 0x01, 0x78, 0xbe, 0x3e, 0x47, 0x1e, 0xbf, 0x53, 0x3f, 0x90, 0x11, 0x65, 0x33, 0xee, 0xb9, 0x58, 0xc1, 0xcb, 0x56, 0xbb, 0x00, 0xee, 0xd4, 0x24, 0xb9, 0x5b, 0x94, 0x7d, 0x41, 0x63, 0x4c, 0x83, 0x41, 0xd8, 0x20, 0x4e, 0x62, 0x96, 0xb9, 0x0e, 0x24, 0x2f, 0xe5, 0x91, 0x0c, 0x04, 0x18, 0x03, 0x7b, 0xfb, 0x60, 0x37, 0x37, 0x52, 0x01, 0xe7, 0x5a, 0xdf, 0x61 }; const uint32_t key_0_publicExponent=65537; const uint8_t key_0_privateExponent[]={ 0x13, 0x73, 0x5f, 0x9d, 0xa0, 0x8b, 0x1c, 0x04, 0x75, 0x7f, 0xe9, 0xaf, 0x46, 0x2b, 0xa4, 0x6b, 0xa0, 0xc1, 0xef, 0x84, 0xdc, 0x25, 0x2f, 0x9c, 0x39, 0xc8, 0x2b, 0x17, 0x27, 0x1a, 0x1c, 0xa3, 0x0a, 0x2f, 0xba, 0xfa, 0xd5, 0x0c, 0xa1, 0x95, 0xdb, 0x36, 0xdb, 0x5e, 0x7b, 0x92, 0x0f, 0xfa, 0xb8, 0xe6, 0xca, 0xef, 0x7b, 0x0f, 0xad, 0xa4, 0xe9, 0x16, 0x1b, 0x16, 0x27, 0x3c, 0x9c, 0x66, 0x59, 0x82, 0xc7, 0x32, 0x3c, 0x4c, 0x6b, 0x08, 0x8b, 0x8f, 0x84, 0xcb, 0x3f, 0x92, 0x2e, 0x20, 0xa4, 0xd1, 0x04, 0x40, 0xdd, 0x2c, 0xa5, 0xb2, 0xb5, 0xa9, 0x93, 0xfa, 0xb8, 0x8d, 0x84, 0x14, 0x72, 0x0c, 0xe1, 0x68, 0x69, 0x41, 0x53, 0xed, 0xf3, 0x51, 0x7c, 0x92, 0x6d, 0x5e, 0x6f, 0x5f, 0xae, 0xc2, 0x5c, 0x47, 0xfa, 0x76, 0xb5, 0xdd, 0x16, 0xc2, 0x44, 0x32, 0x5e, 0xa1, 0x0e, 0x6b, 0xe5, 0x16, 0x15, 0xff, 0xa8, 0x6e, 0x63, 0x07, 0xf3, 0xe8, 0xce, 0xee, 0x94, 0x40, 0x57, 0xb1, 0xe0, 0x59, 0xc1, 0x49, 0xd9, 0x9c, 0xc1, 0x95, 0x45, 0xcd, 0x61, 0x18, 0x1c, 0x0e, 0xb5, 0x8d, 0x0c, 0xc4, 0x71, 0x7b, 0x2c, 0x73, 0xc8, 0x1e, 0xe3, 0xae, 0x58, 0x99, 0x46, 0x42, 0xa4, 0xca, 0x70, 0x5b, 0x6f, 0x38, 0xfe, 0x36, 0x00, 0xe9, 0x07, 0x73, 0x17, 0x40, 0x09, 0xdb, 0xb0, 0x3f, 0x20, 0xc5, 0x45, 0xac, 0x8d, 0x40, 0x2b, 0x16, 0x3c, 0x9b, 0x1c, 0x9a, 0x92, 0xab, 0x1d, 0x30, 0xf0, 0xbd, 0x5f, 0x1a, 0x84, 0x64, 0x44, 0x80, 0x48, 0x58, 0x55, 0x76, 0x2c, 0x1e, 0x97, 0x71, 0x6d, 0xd5, 0x60, 0xde, 0x9f, 0xae, 0x42, 0xf9, 0x5d, 0x4e, 0x3e, 0x0d, 0x70, 0xa7, 0x2f, 0xb8, 0xdf, 0x4d, 0xf9, 0xb1, 0x58, 0x52, 0x94, 0x64, 0xa6, 0xe5, 0xe6, 0xb4, 0x77, 0x20, 0x7f, 0xf9 }; const uint8_t key_0_prime1[]={ 0x00, 0xc3, 0x28, 0x4a, 0xdf, 0xa1, 0x76, 0xbc, 0x08, 0xd7, 0x4d, 0x3f, 0x27, 0x71, 0xe5, 0xca, 0x0d, 0x19, 0x36, 0xa7, 0x45, 0xe5, 0x4a, 0x48, 0x19, 0xfb, 0x7a, 0xde, 0xf3, 0x1f, 0x5b, 0xbc, 0xda, 0x66, 0x18, 0x00, 0x41, 0xb6, 0x44, 0xe5, 0x3a, 0xb5, 0xd8, 0x08, 0xa2, 0x17, 0xba, 0x15, 0xb0, 0xd1, 0xfd, 0x9e, 0x45, 0xbc, 0xc2, 0x0b, 0x0e, 0xe0, 0xbb, 0xbe, 0x04, 0xb3, 0x57, 0xe8, 0x8d, 0x83, 0x64, 0xc3, 0x0e, 0x71, 0x2b, 0x51, 0xd5, 0x39, 0xe7, 0x6c, 0x1d, 0x07, 0x86, 0x76, 0x4e, 0x1a, 0xb4, 0x96, 0xe7, 0xac, 0x7e, 0xe1, 0xda, 0x58, 0xa9, 0x30, 0x62, 0xb9, 0x80, 0xec, 0x6d, 0x32, 0xb5, 0x60, 0xb5, 0x26, 0xd1, 0x5e, 0x68, 0x54, 0xde, 0x30, 0xec, 0x8b, 0x9a, 0xe0, 0x96, 0x85, 0x2c, 0x6e, 0x8b, 0xe5, 0x23, 0x9b, 0xee, 0x1f, 0x38, 0xbf, 0xb0, 0x00, 0x68, 0xae, 0x73 }; const uint8_t key_0_prime2[]={ 0x00, 0xc0, 0xb0, 0x59, 0x28, 0x9c, 0x25, 0xcf, 0x80, 0x2a, 0xf2, 0x10, 0xf7, 0x16, 0xd9, 0x72, 0x58, 0x33, 0x7b, 0x30, 0xbb, 0x91, 0x1d, 0x5e, 0x34, 0xc9, 0xf8, 0x18, 0x15, 0xd7, 0xbf, 0x40, 0x55, 0xf2, 0xb9, 0x68, 0x89, 0x48, 0x9e, 0x6f, 0x0d, 0xa5, 0xe9, 0xc7, 0xbf, 0xa4, 0xe0, 0x1c, 0xd7, 0x79, 0xe0, 0xf8, 0x5a, 0x6e, 0x1e, 0x2d, 0x2f, 0x7b, 0x6e, 0x46, 0xe1, 0xec, 0x65, 0xb8, 0x0f, 0x4b, 0x41, 0xab, 0x8e, 0x9b, 0xbd, 0x6b, 0xcf, 0x5c, 0x7a, 0xcd, 0x4f, 0xa8, 0x99, 0x11, 0x62, 0x1e, 0xd4, 0x12, 0x42, 0xf7, 0xa3, 0xd2, 0x84, 0xcb, 0xd0, 0xef, 0x65, 0xde, 0x02, 0xef, 0x2e, 0xb0, 0x00, 0xb0, 0xe0, 0x62, 0xf6, 0x53, 0x9d, 0xa7, 0x0c, 0x0e, 0x9b, 0x48, 0x85, 0x67, 0x9d, 0x6d, 0x41, 0xca, 0x13, 0xc2, 0x30, 0x95, 0xfb, 0xf0, 0x27, 0x3b, 0xee, 0xf6, 0xe8, 0x11, 0xdb }; const uint8_t key_0_exponent1[]={ 0x20, 0x75, 0x4f, 0x1e, 0xaa, 0xa8, 0x28, 0xd5, 0xff, 0x99, 0x25, 0x6b, 0xd6, 0x11, 0xb5, 0xed, 0x3f, 0xc8, 0x4b, 0x41, 0xe0, 0xc4, 0xde, 0x01, 0x14, 0x46, 0x77, 0x56, 0x50, 0x5c, 0xdd, 0xa8, 0x25, 0x5a, 0xd0, 0x90, 0x1d, 0x54, 0x90, 0x1b, 0x97, 0xaa, 0xfa, 0xa4, 0x9a, 0xf5, 0xa4, 0x2d, 0xe8, 0x7f, 0x1a, 0x17, 0xd7, 0x31, 0x1e, 0xcd, 0xb6, 0xab, 0x03, 0x0b, 0x9d, 0x18, 0x7d, 0xe1, 0x2b, 0x7d, 0x52, 0xc3, 0xd0, 0x26, 0xb8, 0x51, 0x92, 0x73, 0xdf, 0x13, 0x64, 0xf1, 0x04, 0x34, 0x31, 0x54, 0xdf, 0xd4, 0x60, 0x68, 0x2a, 0x00, 0x3a, 0xc6, 0xc8, 0xf9, 0x62, 0x89, 0x02, 0xc9, 0x96, 0xa9, 0x7c, 0x10, 0x25, 0x08, 0xa5, 0x7f, 0x0c, 0xbe, 0x77, 0xbc, 0x9f, 0xeb, 0x7e, 0x77, 0x0a, 0x67, 0x3d, 0x6b, 0x9f, 0x0c, 0xb1, 0x1e, 0x85, 0xaa, 0xd6, 0x96, 0xdb, 0x3a, 0x8d, 0xe9 }; const uint8_t key_0_exponent2[]={ 0x5f, 0x5a, 0x25, 0x14, 0xca, 0x88, 0x8f, 0x71, 0x5e, 0x4f, 0x21, 0x84, 0x14, 0xa3, 0x90, 0x49, 0x03, 0x58, 0xcf, 0xd9, 0xd1, 0xca, 0xd5, 0xa6, 0x8b, 0xd7, 0xa0, 0x9b, 0x96, 0x83, 0x06, 0xe4, 0x41, 0x53, 0xec, 0xde, 0x1a, 0xb8, 0x84, 0x3e, 0x1d, 0xbf, 0x5d, 0x60, 0x81, 0xc7, 0x81, 0x9e, 0x43, 0xaa, 0xc7, 0x5b, 0x80, 0xa8, 0xa0, 0x35, 0xa2, 0x00, 0x05, 0x45, 0xa1, 0x85, 0x08, 0x9b, 0x50, 0xe3, 0x73, 0x71, 0x03, 0xb2, 0xad, 0xda, 0x14, 0x6a, 0x94, 0x94, 0xf9, 0xda, 0x9d, 0x56, 0x8f, 0xe8, 0xe4, 0x0c, 0x8d, 0x9d, 0x5c, 0xfc, 0xe8, 0x1b, 0x41, 0x8c, 0x88, 0x5b, 0xad, 0x5e, 0xce, 0x2b, 0xd9, 0x5b, 0x80, 0xbd, 0x62, 0xcd, 0x5e, 0x2f, 0xc2, 0x3e, 0xa7, 0x99, 0x94, 0x97, 0xbb, 0xcc, 0x55, 0xa2, 0x87, 0x73, 0x21, 0x95, 0x65, 0xd7, 0x14, 0x7a, 0x81, 0x66, 0x80, 0x07 }; const uint8_t key_0_coefficient[]={ 0xb3, 0x83, 0xf8, 0x90, 0x24, 0x74, 0xba, 0x23, 0xe9, 0x3a, 0xe6, 0x39, 0x4c, 0x63, 0x9d, 0x35, 0xe3, 0x6f, 0x86, 0x16, 0xa7, 0xcb, 0x35, 0xa5, 0x60, 0xd4, 0x3f, 0xe3, 0x07, 0xac, 0x4c, 0x74, 0x49, 0x85, 0x5c, 0x0e, 0x2d, 0xe4, 0x4b, 0xd5, 0x7f, 0x26, 0x98, 0x82, 0x94, 0x1a, 0xc5, 0xda, 0x9c, 0x65, 0x29, 0x46, 0x0b, 0xb7, 0xf6, 0x64, 0xc8, 0xf2, 0x7d, 0xbc, 0x70, 0x6d, 0x63, 0x91, 0x6a, 0xcb, 0x0c, 0x61, 0x8c, 0x0a, 0xaf, 0x1f, 0x7f, 0xd0, 0x77, 0x96, 0x78, 0x0d, 0xbd, 0x57, 0x72, 0xc6, 0xab, 0x01, 0x4f, 0x49, 0xb9, 0x70, 0x62, 0x40, 0x5e, 0x9f, 0x0e, 0x00, 0xb5, 0xc6, 0xd0, 0x59, 0xd1, 0x07, 0x82, 0xa2, 0x75, 0xe3, 0x26, 0x49, 0x3a, 0x39, 0x5c, 0x61, 0x9b, 0xd7, 0x3a, 0x40, 0xaa, 0x26, 0xc0, 0xec, 0x62, 0x15, 0x14, 0x16, 0x36, 0xc0, 0x29, 0x3b, 0x74, 0x79 }; // Private-Key(1024 bit) (Big Endian) const uint8_t key_1_1024_modulus[]={ 0xac,0x79,0xe8,0xb0,0xd2,0x11,0x64,0x9a,0x1c,0xe4,0x24,0xf6,0x3c,0xfe, 0x7c,0x6a,0x3a,0x3e,0x0b,0x07,0xae,0xa9,0x79,0x6f,0x64,0x4e,0xf0,0x5c,0x4c, 0xb4,0xa7,0x38,0xc9,0xde,0x4a,0x36,0x68,0x7f,0x98,0x05,0xe3,0x3c,0xf8,0xd6, 0xd2,0xf1,0x9f,0xd9,0x88,0x9d,0xa7,0xcf,0x0d,0xe5,0x92,0x8d,0x2b,0x44,0x24, 0xa3,0xa7,0x20,0xf4,0xd4,0xd7,0xe5,0xf8,0x07,0x24,0xd7,0xd2,0x32,0x2c,0x8f, 0xcb,0xd8,0xf8,0xe0,0x97,0x69,0xcb,0xab,0x4c,0xfb,0xf3,0xa2,0xe5,0x43,0x8c, 0xb1,0x9f,0xa6,0xac,0xe9,0x86,0x88,0x85,0x74,0xf2,0xb2,0xdc,0x87,0x56,0xf5, 0x99,0x96,0x03,0x70,0xa2,0x5d,0x26,0x26,0x12,0x20,0x09,0x3e,0x5f,0xb0,0x3b, 0xbd,0xee,0x19,0x9c,0x96,0xd8,0x82,0x22,0x91}; const uint32_t key_1_1024_publicExponent=65537; // (0x10001) const uint8_t key_1_1024_privateExponent[]={ 0x03,0xe5,0xc9,0x5d,0x5d,0x91,0xe9,0x0d,0x16,0x84,0x0d,0x55,0xc7,0x31,0x15, 0x0c,0xad,0x7e,0x43,0x6f,0x8c,0x01,0xe6,0x6d,0x9e,0xfd,0xad,0xae,0xd8,0x48, 0xe8,0xd2,0x7e,0xb5,0x58,0x45,0xfc,0x7c,0x8d,0xa9,0xec,0x65,0xaf,0x55,0xe3, 0x74,0x74,0x61,0x4d,0x16,0x0a,0xf9,0xc1,0xdd,0xa3,0x3f,0x2f,0x70,0x1d,0xc7, 0xd8,0xfa,0x04,0xae,0x52,0x7d,0xe3,0x20,0xc6,0xb5,0x5b,0x6b,0xd7,0x0b,0x02, 0x2a,0xcf,0x28,0xf4,0x34,0x7d,0x46,0x69,0x15,0xf0,0x95,0xd0,0x7b,0x9a,0xa4, 0x24,0x9b,0x27,0x49,0x99,0x49,0x14,0x27,0xa9,0x95,0x89,0x6e,0xff,0x96,0x0c, 0x02,0xb7,0x46,0xab,0x95,0x46,0x34,0x33,0xee,0xe1,0x1a,0x4c,0x3a,0x09,0x19, 0xf3,0xda,0x2c,0x67,0x8e,0xcc,0x10,0x71}; const uint8_t key_1_1024_prime1[]={ 0x01,0xb5,0x09,0x1a,0x06,0xe7,0xfa,0x1f,0x6b,0x52,0x3f,0xe9,0x57,0x3c,0xd9, 0xe0,0xdb,0x1a,0x32,0x05,0x0c,0xf8,0xba,0x84,0x55,0xc5,0x17,0x64,0xb6,0x02, 0x4f,0xcf,0x30,0x07,0x3a,0x1c,0x13,0x14,0xfb,0x5f,0xf6,0xcf,0x4b,0xeb,0x4d, 0x11,0x6e,0x78,0x93,0x2b,0x38,0xd9,0x8a,0x59,0x0f,0xba,0x57,0xb6,0xc5,0x50, 0x20,0xf0,0xd5,0x23,0x55}; const uint8_t key_1_1024_prime2[]={ 0x65,0x07,0xcd,0x1e,0x84,0x0f,0x49,0x20,0xa8,0x61,0xff,0x94,0x00,0x2c,0x28, 0xe9,0x5c,0x19,0xa1,0x11,0x16,0xf3,0xf2,0xbf,0x42,0x8c,0x03,0x66,0xeb,0x1e, 0x5e,0xe6,0x28,0xb5,0xf5,0x03,0x2b,0x31,0x36,0x40,0xb7,0xd5,0xb6,0x68,0x8f, 0x62,0xdf,0xca,0xe2,0x38,0xc4,0xac,0xb5,0x7f,0xf3,0xa8,0xc6,0x16,0x32,0xec, 0x9f,0x50,0x7a,0x4d}; const uint8_t key_1_1024_exponent1[]={ 0x00,0xa2,0x5d,0x8b,0x49,0xdd,0x8d,0x53,0x76,0xef,0xcb,0xc6,0xc9,0x1e,0x56, 0x63,0xef,0x82,0xbf,0xea,0x98,0x73,0x1f,0xf8,0x62,0x55,0x22,0xe7,0xcb,0xa6, 0xf8,0x37,0xa5,0x44,0x4a,0x16,0x7c,0x10,0x63,0x83,0xb7,0x92,0x34,0x46,0x6b, 0x0f,0x7a,0xd7,0x58,0xf5,0xc9,0xdd,0x28,0x45,0x06,0x4e,0xd8,0x9f,0x92,0x96, 0xbe,0x66,0x3b,0x09,0x31}; const uint8_t key_1_1024_exponent2[]={ 0x38,0xf7,0xaf,0x27,0x97,0xdb,0x6e,0xa6,0xa5,0x8b,0xac,0xab,0x6d,0x75,0x79, 0x14,0x2c,0xc4,0x9e,0xd7,0x9e,0x13,0xac,0x3b,0x40,0x70,0xe6,0xb2,0x2f,0xbd, 0x8e,0x51,0x45,0x7f,0x64,0x4a,0x87,0x1e,0x56,0xb3,0x23,0x75,0xb4,0x47,0x3d, 0x22,0xc9,0x82,0x03,0x11,0x73,0x84,0xd7,0x4a,0xf0,0xbf,0xa8,0x02,0x78,0x70, 0x88,0x5c,0xbe,0xb9}; const uint8_t key_1_1024_coefficient[]={ 0x01,0xb1,0x42,0xc6,0xc3,0xa0,0x76,0x2c,0x68,0x0f,0x42,0xd1,0x7c,0xe3,0x63, 0xc4,0xb9,0xb7,0x12,0x56,0xa7,0x59,0xe1,0x20,0xb0,0xd7,0xa4,0xb8,0xa0,0x20, 0x75,0x99,0x8d,0xf3,0x66,0x4a,0x90,0x9e,0x0a,0xc9,0x93,0x23,0x9f,0xb5,0xbb, 0x17,0xc1,0xf4,0xe5,0x2f,0x2a,0xfe,0xa3,0xd5,0x4b,0xf0,0xf3,0xec,0xd2,0x55, 0xe3,0x24,0x7d,0x91,0x4e}; const uint8_t key_1_1024_coefficient_inv[]={ 0xdf,0x63,0x35,0xd4,0x04,0xf5,0x2c,0x4b,0xbe,0x63,0xe6,0xa6, 0xe6,0xdf,0x1d,0xac,0xaf,0x9f,0xa1,0xa9,0x8a,0x34,0x2c,0x17, 0xd2,0xe1,0x63,0x12,0x82,0x86,0xad,0x3b,0xc4,0x03,0x9f,0xac, 0x44,0x20,0x16,0x51,0xcd,0xf7,0xdf,0x2e,0xba,0x22,0xb2,0xed, 0x14,0xe6,0xb4,0x8b,0x2c,0x8f,0xb2,0xc8,0xe5,0xa7,0xa5,0x48, 0x0a,0x71,0xac}; // Private-Key(2048 bit) (Big Endian) const uint8_t key_1_2048_modulus[]={ 0xd5,0x00,0x56,0x84,0x9b,0x61,0xe6,0x7e,0xf8,0xfb,0xb8,0xce,0x49,0x76, 0x0e,0x03,0xfb,0xfc,0x40,0x34,0x6e,0xcf,0x50,0xae,0x0a,0xe5,0x2e,0x04,0x1a, 0x6b,0xff,0x14,0x75,0x6a,0xde,0xe8,0x2f,0xd6,0xa7,0xf1,0xdf,0xad,0x44,0x22, 0x96,0xf0,0x98,0xde,0x25,0x6f,0xb4,0x7e,0x66,0x28,0x5b,0x86,0xe5,0x5d,0xc9, 0x73,0x17,0xa2,0x2d,0x5f,0x1e,0x62,0xe7,0x90,0xfc,0xa4,0xe7,0x1d,0x22,0xdd, 0x89,0xfd,0x04,0x8c,0x3e,0x68,0x0e,0x6c,0x00,0x44,0x45,0x11,0xd8,0xb8,0x7b, 0x86,0xea,0xa4,0x8e,0xf3,0x6d,0xd7,0x14,0xbd,0x4f,0x5a,0x1d,0x81,0x21,0x4d, 0x16,0x5f,0x81,0xd9,0x3b,0x13,0xee,0xa4,0xda,0xdd,0x63,0x9c,0x64,0x3d,0xff, 0xc3,0x33,0xaa,0x50,0x99,0x7c,0xa0,0x1a,0xa2,0x68,0x9e,0xd5,0xee,0x3b,0x42, 0xf6,0x06,0x6e,0x44,0xb5,0x02,0x7c,0x7e,0x3c,0x00,0x73,0x1d,0x1e,0xef,0x66, 0xa7,0xa0,0x8b,0xc9,0x2b,0x55,0x63,0xf1,0x19,0x1f,0x55,0xb6,0xba,0xa0,0xaf, 0xc7,0x87,0xd7,0xf2,0x2c,0x2f,0x08,0x70,0xd2,0xa6,0x8b,0x7d,0x11,0xa2,0x13, 0x5c,0x19,0x1c,0x5e,0x9b,0x66,0x7b,0xd8,0x37,0xba,0x1b,0x3b,0x23,0xef,0xa2, 0xfc,0x0b,0xc5,0xfd,0x0f,0x94,0xf0,0x4c,0xb2,0x89,0x14,0xfa,0x79,0xc2,0xbc, 0x02,0xb0,0x06,0x71,0x32,0x45,0x0e,0x89,0xa9,0x2b,0x58,0x2a,0x12,0x31,0xb6, 0xe1,0x7d,0xfb,0x4e,0x55,0xb5,0x92,0xe6,0xf4,0xfc,0xcb,0x49,0xc7,0x1d,0x1e, 0x4a,0x73,0xdc,0xd1,0x67,0x2b,0x81,0xcd,0x60,0x83,0xb7,0xf9,0xde,0xa6,0x68, 0x7c,0xd1 }; const uint32_t key_1_2048_publicExponent=65537; // (0x10001) const uint8_t key_1_2048_privateExponent[]={ 0x2d,0x5f,0x0d,0x0e,0xe2,0x2a,0x50,0x76,0xeb,0x82,0x73,0x33,0x3d,0xe2,0xaf, 0xc9,0x99,0x7b,0x7a,0x11,0xb1,0x28,0xe7,0xfe,0xaa,0xc3,0x76,0xb1,0xd9,0x0e, 0xf8,0x1e,0xdb,0x84,0x10,0x47,0x55,0x29,0x5c,0x4c,0xe1,0x60,0x7f,0x0a,0xff, 0x2b,0xf0,0xe4,0x21,0x05,0x52,0x65,0x3a,0x4d,0x8e,0x71,0x85,0x9a,0x1c,0xb7, 0x2f,0x69,0x94,0x50,0x96,0xa0,0x6a,0xc3,0x2f,0x8d,0xd0,0xcd,0x1c,0x08,0x24, 0xc4,0x88,0x9b,0x77,0x0f,0xa3,0x42,0xce,0x2b,0xbc,0xaa,0xb8,0x87,0x53,0x88, 0xc1,0xa2,0x9b,0xf0,0xae,0x8d,0x0a,0x15,0xe9,0x39,0x40,0xdf,0xa8,0xc0,0x4a, 0xeb,0xbd,0x35,0x10,0xa8,0x86,0x45,0x07,0x79,0xf1,0x25,0xf7,0x14,0x5d,0xce, 0xae,0xca,0xb0,0xb0,0x81,0x23,0x79,0x88,0x8b,0x23,0xa7,0x64,0xf2,0x6c,0xf4, 0x68,0xa3,0x77,0xed,0x1d,0xe0,0xf1,0xe5,0x6e,0x9b,0x3b,0x6f,0x19,0x1f,0x0d, 0x9d,0xc6,0x86,0xcf,0x50,0x1d,0x62,0x73,0x28,0x54,0x6b,0xaa,0x4d,0x20,0xab, 0xd1,0x46,0xd2,0x8c,0x4a,0xee,0x07,0xe6,0xcf,0x7b,0x61,0xdc,0xd5,0xe6,0x72, 0x4e,0x1c,0x4d,0x29,0xb4,0xf9,0x37,0x49,0xfe,0x3a,0x7c,0x84,0x4f,0x68,0x17, 0x4c,0xd3,0xe7,0xf3,0x29,0xc5,0x45,0xe8,0xf6,0x6a,0x90,0x82,0xa2,0x2c,0x38, 0x7c,0xe2,0x78,0x18,0xf0,0xf2,0xe2,0x63,0x46,0x05,0x2e,0xbf,0xc3,0x46,0xa9, 0xcc,0xb8,0x30,0x3f,0xa1,0x85,0x5f,0x4f,0x1d,0x80,0x29,0xd1,0x5d,0x4d,0xd7, 0x1f,0xa2,0xf0,0xf0,0xbe,0x9f,0xbb,0x00,0x63,0x4b,0xdc,0x07,0x36,0x1e,0xa7, 0x21}; const uint8_t key_1_2048_prime1[]={ 0xdb,0x6b,0x23,0x85,0x3d,0x03,0x9f,0x1a,0xe5,0x68,0x97,0x32,0xd1,0x9f, 0xb7,0xa6,0x6a,0xfe,0xd8,0x4d,0xd9,0x75,0x6a,0xfd,0xd8,0xf5,0x30,0x92,0x8c, 0xc7,0x36,0x53,0x28,0xbb,0x63,0x8b,0x3b,0x0d,0x1a,0x1f,0x16,0x76,0x4d,0x3e, 0x34,0x80,0x68,0x47,0x58,0xa2,0xa5,0x82,0x00,0xf0,0x17,0x55,0xb7,0xec,0xa5, 0x63,0xdd,0x68,0xfe,0xcd,0x0c,0x56,0xed,0x81,0x8a,0x98,0x3e,0xfc,0x13,0x4a, 0x41,0x04,0xdb,0x44,0x86,0xf1,0xa5,0xd6,0xf4,0x8a,0xab,0x2b,0x20,0x13,0x7f, 0x75,0x75,0x1b,0x4b,0x7b,0xa3,0x22,0x84,0xfc,0xde,0x6d,0x42,0xf3,0x41,0xdf, 0x3f,0x5d,0x87,0xbd,0xad,0x73,0xfd,0xdb,0x1a,0xce,0x0c,0x87,0x83,0x15,0xfd, 0xe7,0x0c,0x83,0x74,0xa5,0x11,0xb6,0xb9,0x1f}; const uint8_t key_1_2048_prime2[]={ 0xf8,0x83,0x4f,0xaa,0xae,0xfd,0xee,0x37,0x87,0xad,0x03,0x71,0xcf,0xd7, 0xcc,0x5f,0xe3,0x42,0x07,0x76,0xe4,0xf2,0xe4,0x0e,0xa9,0x3e,0xf7,0x40,0xd7, 0x2e,0x10,0x30,0x1b,0x4c,0x18,0xff,0xb5,0x5f,0xd8,0x99,0xf5,0xa3,0xb5,0xb7, 0xbc,0xac,0xc5,0xbb,0xf4,0x1f,0xca,0x6b,0x3f,0xa9,0x81,0x1c,0x45,0x9c,0x9e, 0x02,0x8f,0x4c,0xf5,0x80,0xc6,0x05,0xa9,0x84,0x4e,0x15,0x9c,0x7c,0x3f,0x74, 0x51,0x9a,0x2a,0x9e,0xac,0x7e,0xf3,0xf0,0x97,0x0b,0xe4,0xa0,0x6e,0x8e,0x6a, 0xc4,0x80,0x89,0x11,0x8c,0xfb,0xe7,0x4d,0xa0,0x07,0xf4,0xbc,0x2b,0xb4,0xa0, 0xa3,0xed,0xe9,0x30,0x87,0x43,0xea,0x38,0x3b,0xad,0xc9,0x5a,0x9a,0xc4,0xd4, 0x9b,0x62,0xbc,0x3c,0x1c,0x0d,0xc3,0xdc,0x0f}; const uint8_t key_1_2048_exponent1[]={ 0x9a,0xf4,0xb7,0xfa,0x21,0x93,0xcc,0x2a,0x47,0x77,0x2c,0xc8,0x73,0xe8, 0x12,0xdf,0x91,0x52,0x76,0xd9,0xcb,0xc8,0x33,0x8e,0x20,0x49,0x50,0x4b,0x3e, 0xe6,0x75,0x44,0x17,0x50,0xf7,0x44,0xdd,0xa8,0x2c,0x19,0x66,0x58,0x97,0xc6, 0x65,0x77,0x85,0xad,0x55,0x38,0x50,0x20,0x56,0x9f,0x38,0x2b,0x8e,0x1f,0xae, 0xd1,0xaf,0x0c,0xb6,0x5d,0x82,0xe8,0x65,0x05,0x06,0x26,0xec,0xdc,0x42,0x97, 0x3f,0x01,0xba,0x04,0x54,0x34,0x96,0x05,0x0f,0x60,0x5a,0xef,0xb2,0xd0,0x72, 0x44,0x36,0x36,0xd7,0x80,0xf2,0x3d,0xaf,0xa3,0x91,0x45,0xa2,0x71,0x7e,0xc4, 0xb5,0xd0,0x4c,0xcb,0xb4,0x92,0x64,0xe5,0xf6,0xb1,0x2b,0x82,0x0c,0x1e,0x5c, 0xd8,0x6e,0x2a,0xec,0x16,0xa3,0x42,0xe2,0xcb}; const uint8_t key_1_2048_exponent2[]={ 0x0c,0x71,0xf7,0x01,0x63,0x36,0x10,0x41,0xf3,0xa7,0x74,0x6e,0xb4,0xab,0xe7, 0xee,0x3d,0x61,0x47,0x22,0x6b,0x20,0xc6,0xce,0xfd,0x26,0xcc,0x17,0x11,0x2f, 0x9b,0x5b,0xed,0x62,0x08,0x36,0x76,0x0c,0xd0,0xba,0x15,0x15,0x17,0xba,0x95, 0xd6,0x49,0x28,0xba,0x77,0x05,0x1a,0x0d,0xdc,0x1d,0x3d,0x1f,0x37,0x52,0xaa, 0x6a,0x26,0xbe,0x7c,0xae,0x6e,0x06,0x29,0x3c,0x07,0xd5,0x08,0x5b,0xdd,0x25, 0x61,0x05,0x15,0x61,0x2a,0x12,0x69,0x50,0x07,0x26,0x71,0xea,0x57,0x73,0x7d, 0x57,0xba,0x85,0x88,0x7b,0xec,0xff,0x74,0x2e,0x31,0xd1,0x62,0x96,0xef,0x1c, 0x86,0x83,0x91,0x0c,0x95,0x18,0x1b,0xac,0xd1,0x6d,0x2d,0xfe,0x66,0x31,0x07, 0x7f,0x10,0x52,0x2a,0x4d,0x7e,0x2b,0x7d}; const uint8_t key_1_2048_coefficient[]={ 0x0c,0x23,0xef,0x4e,0x84,0xf3,0x92,0x9f,0x2d,0xcd,0x4c,0x45,0xde,0x10,0x85, 0x52,0x22,0xf8,0x6c,0x6e,0xb3,0x86,0x14,0x94,0x5b,0x64,0xf3,0x83,0xfd,0xd9, 0x56,0x72,0xbf,0x98,0x53,0x14,0x69,0x30,0xf1,0xb1,0xad,0x9c,0xc5,0x12,0x00, 0xf6,0x4e,0x13,0x6c,0xa1,0x20,0xf2,0x1b,0x39,0xa0,0xa3,0xff,0xe6,0xc7,0x0e, 0x7f,0xa5,0x2e,0xad,0x2a,0x97,0xb3,0x45,0x6d,0xb5,0xdf,0x77,0x28,0x09,0x20, 0x8c,0xed,0x1d,0x1e,0xfe,0xa2,0xab,0x23,0x6a,0x43,0x90,0x9f,0xe1,0x48,0xfd, 0x32,0x88,0x13,0xb6,0xc5,0xbf,0x43,0x6c,0xd2,0xb4,0x0e,0xa1,0x34,0x9f,0x47, 0x71,0xf6,0xb8,0xde,0x24,0x11,0x32,0xfb,0x30,0x9f,0xb5,0x2f,0x18,0x90,0xa8, 0x15,0xd7,0xaa,0x65,0xe9,0x3e,0xd0,0x76}; const uint8_t key_1_2048_coefficient_inv[]={ 0xea,0xc3,0x45,0x5b,0x36,0x39,0x99,0xd0,0xb5,0x4d,0xc4,0xfb, 0x97,0x74,0xf2,0x6f,0x7a,0x7c,0xf4,0xa3,0xdb,0xd4,0x42,0x22, 0xba,0x85,0xba,0xf8,0x9c,0x16,0x83,0xcd,0xb3,0xe7,0x53,0x3c, 0x93,0x1a,0xd3,0x97,0xf2,0xea,0xae,0x45,0xcc,0x6c,0xc2,0x0b, 0x98,0x2d,0xab,0x70,0xf0,0x4d,0xa0,0xe2,0xf0,0x6b,0x62,0xe1, 0x28,0xae,0x44,0xb6,0x02,0x86,0x2d,0x20,0xe6,0xd2,0x9c,0xd5, 0x81,0x2f,0x0a,0xd6,0x31,0x14,0x81,0xbc,0xb6,0x86,0xd2,0xc7, 0x25,0x6a,0xb4,0x32,0x6e,0x1b,0x28,0x0d,0x40,0xc3,0xc8,0x6a, 0x47,0x3f,0x8e,0xd5,0xe5,0xa8,0xb7,0x52,0xc8,0xa4,0x33,0x05, 0x2a,0xbc,0x44,0xdc,0x87,0x12,0x9b,0x29,0x06,0xa7,0xe3,0x96, 0x58,0x73,0x75,0x89,0xdb,0x47,0x1d,0x18}; const uint8_t key_2048_all_zeroes[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00}; const uint8_t key_1026_prime_1[]={ 0x03,0xb1,0x2f,0x3e,0x76,0x6a,0xff,0xdd,0x2f,0x2b, 0x04,0x16,0xae,0xb0,0x6c,0xf0,0xff,0x1b,0x14,0x5d, 0x3a,0x47,0x5b,0xef,0x72,0xd5,0x07,0xa4,0xeb,0x48, 0x7d,0x69,0xce,0x8b,0x4c,0x66,0x69,0x6b,0xde,0x1f, 0xf8,0x1c,0x06,0x53,0xaf,0x27,0x17,0x28,0x57,0x52, 0xe5,0xc3,0x02,0xc6,0x66,0xa1,0x80,0xbc,0xfa,0x01, 0xd8,0x9d,0x34,0x08,0x8b, }; const uint8_t key_1026_prime_2[]={ 0x9e,0x81,0x62,0x91,0x77,0x44,0x63,0xae,0x83,0xd0, 0x8e,0x49,0x88,0xf9,0x70,0xde,0xf5,0x9e,0x62,0xb0, 0x23,0x18,0xbd,0x2a,0x7a,0x5b,0x40,0x22,0xbc,0x84, 0x26,0x23,0x3f,0xae,0x89,0x6e,0xf7,0x47,0xba,0x53, 0x26,0x3a,0x6e,0x9c,0xb9,0x7b,0xd4,0xf2,0x57,0x02, 0x58,0xac,0x61,0x29,0x0a,0xa5,0xa7,0xb7,0xc2,0x39, 0x64,0xeb,0x5a,0x45, }; const uint8_t key_1026_modulus[]={ 0x02,0x49,0x38,0xdd,0x48,0xb9,0xbb,0x02,0x19,0x5c, 0x0c,0x55,0x94,0x94,0xb2,0x31,0x81,0x61,0x59,0x19, 0x01,0x4a,0x07,0xd3,0xac,0x3f,0xd1,0x27,0xfb,0xc6, 0xec,0x31,0xd9,0x0c,0x9c,0xd9,0x9a,0x97,0x3b,0x91, 0x0c,0x6e,0x7e,0xae,0xa2,0x01,0xb0,0x2b,0x7b,0x38, 0x2c,0xc4,0x0d,0xcc,0x86,0xd9,0x2f,0xf5,0x1d,0xcd, 0x60,0x79,0xd8,0xe6,0x0d,0xbd,0xb0,0x0d,0xca,0xee, 0x3d,0x9a,0xd4,0xa2,0x0a,0x7b,0x57,0x8d,0xb0,0x82, 0x15,0x79,0x98,0x9f,0x9d,0xe1,0x3e,0x31,0x12,0x32, 0xd5,0xac,0xbe,0x72,0xe2,0x91,0xe5,0xd0,0x6f,0x0e, 0x54,0xeb,0x75,0xa8,0xff,0x2d,0xd9,0x38,0xb9,0xec, 0xc4,0xa2,0xd7,0x59,0x87,0x84,0x4e,0xa7,0x07,0xbe, 0x13,0x5a,0xb5,0x85,0xb3,0xcd,0xa0,0x2b,0x77, }; const uint8_t key_1026_public_exponent[]={ 0x01,0x00,0x01, }; const uint8_t key_1026_private_exponent[]={ 0x35,0xa7,0x5d,0x7e,0x53,0xec,0xe5,0xc9,0xde,0x6b,0x11, 0x13,0x90,0xb8,0x6f,0x9a,0x7d,0x8a,0xd6,0x24,0x8c,0x9d, 0x80,0x16,0x1c,0x39,0xb8,0x51,0x38,0x91,0x22,0x16,0xd4, 0xb5,0xb2,0xab,0x9e,0x2e,0xeb,0x62,0xf8,0xe4,0x6b,0x6d, 0x55,0xfb,0x49,0x59,0x40,0x32,0xb6,0x7c,0xcf,0x62,0x13, 0x9a,0x76,0x7e,0x17,0x7c,0xbf,0x5f,0x17,0xe4,0x08,0x6e, 0x31,0x12,0x06,0xd0,0x83,0x23,0x85,0x73,0xcb,0xa6,0x2c, 0xcb,0xa8,0xfd,0x7b,0x84,0x0b,0xc8,0xdf,0xdc,0xa4,0xe4, 0xb4,0x8f,0xaa,0xe8,0x2d,0x82,0xc2,0x13,0x95,0xc6,0x6a, 0x1f,0x1f,0xbe,0x35,0x64,0xc0,0x76,0x57,0x71,0x4a,0x73, 0xe8,0xca,0x3f,0x2e,0x3d,0xc0,0xd5,0xc6,0x73,0xda,0x46, 0x49,0xdc,0xe0,0x51,0x10,0x8b,0x15, }; const uint8_t key_1026_exponent1 []={ 0x02,0x7f,0xc0,0x91,0x8f,0xc7,0x96,0xcd,0xd8,0x6a, 0x4e,0x47,0x28,0x10,0x84,0x7c,0x8e,0xbf,0x7e,0x86, 0x27,0xb7,0x3b,0x34,0x14,0xce,0xba,0x70,0xd7,0x4c, 0x66,0x8e,0xe2,0x5d,0x88,0xe5,0xdc,0xbf,0x45,0x46, 0xf0,0x41,0xcf,0xca,0x7e,0xc8,0x7f,0xb5,0x2f,0x7e, 0x0d,0xc4,0x74,0x31,0x64,0x30,0x36,0x9a,0x32,0xc2, 0x63,0x22,0xec,0xa0,0x47, }; const uint8_t key_1026_exponent2 []={ 0x10,0x7a,0x48,0xe1,0xf0,0x71,0x26,0x9f,0xb4,0xca, 0x50,0x90,0x6a,0x71,0xeb,0xfe,0xf1,0xaf,0xc6,0x78, 0xa3,0x1d,0x66,0x44,0xed,0x35,0x61,0x44,0x7b,0x2e, 0x8d,0xbc,0x6a,0x59,0x5d,0xa6,0x30,0x84,0xbf,0x64, 0xf7,0x7b,0x69,0x96,0x57,0x5d,0xfd,0x34,0x38,0x41, 0x61,0x30,0x82,0x65,0x3e,0xdb,0x1b,0xc5,0x69,0xa6, 0x87,0xcc,0x43,0xb5, }; const uint8_t key_1026_coefficient []={ 0x01,0x7d,0x95,0xd8,0xa6,0x3a,0xa5,0x4a,0x3d,0x23, 0x30,0x64,0x7e,0x8f,0x15,0x70,0xe5,0x4e,0xe7,0x1f, 0xb6,0xb3,0x6c,0x73,0x68,0xca,0x3b,0x6e,0x4d,0x81, 0xb5,0x60,0x8d,0xdb,0x8a,0x38,0xd5,0x8d,0xf3,0xae, 0x3e,0x11,0x00,0xd7,0xc3,0xf3,0x8d,0x3e,0xbe,0x9b, 0x4d,0xa1,0x24,0x23,0x3a,0x79,0xf4,0xf0,0xf5,0x68, 0xf1,0xb5,0xfb,0x63,0x56, }; const uint8_t key_1027_prime_1[]={ 0x05,0xf6,0xb7,0xbd,0x4b,0xa9,0x62,0x61,0x49,0x43, 0x04,0x58,0x6f,0xb0,0x82,0x3d,0x0b,0xee,0xa7,0x38, 0x61,0xa8,0xe2,0x99,0x7e,0x43,0x4d,0x83,0x40,0x54, 0xa8,0x99,0xf1,0xaa,0xb7,0xd5,0xe8,0x53,0x70,0x75, 0x17,0xa4,0xbd,0x3f,0x46,0xd3,0x65,0x69,0x8e,0xa9, 0xd3,0x24,0x3b,0x3c,0x58,0xfc,0xed,0x9d,0xe6,0xe5, 0x7e,0x87,0xc8,0x1d,0x5d, }; const uint8_t key_1027_prime_2[]={ 0x88,0x0e,0x76,0xfa,0x5f,0x0f,0xd4,0xe4,0x4c,0xd7, 0x42,0x66,0xbd,0xb5,0x9e,0x90,0x65,0xca,0x5a,0x5a, 0xca,0xcb,0xa4,0x33,0xa7,0x51,0xa3,0xdf,0x62,0x45, 0x43,0x29,0xd4,0xc0,0x11,0x62,0xf0,0xe2,0xf4,0x7f, 0x09,0x40,0x77,0x25,0xff,0x4b,0xe1,0xec,0x14,0x78, 0xea,0x59,0xa8,0x76,0xd4,0xd9,0x18,0xe2,0x5d,0x48, 0x80,0x39,0x8a,0x8d, }; const uint8_t key_1027_modulus[]={ 0x03,0x2b,0x67,0xe0,0x2a,0x63,0xbb,0xdc,0xab,0xda, 0x7a,0xba,0xb0,0x5e,0x73,0xb7,0x6c,0x8d,0x66,0xff, 0x0e,0x8f,0xa5,0x83,0x0f,0xde,0xee,0x8d,0xa8,0x02, 0x3c,0xca,0x48,0xd2,0x9e,0xac,0x4b,0x2b,0x30,0xdf, 0x41,0xfb,0x4d,0x34,0xc4,0xad,0x97,0xfb,0xc6,0x14, 0x71,0xff,0xe4,0xfb,0x2d,0x41,0x33,0xd5,0x34,0x0b, 0x76,0x52,0x1a,0x61,0x8c,0x26,0x2e,0xa2,0x97,0x82, 0xf1,0xa7,0x2d,0x8a,0x49,0xd7,0x30,0xb6,0x7d,0xe3, 0x64,0xcc,0x95,0xd6,0x29,0x5d,0xa9,0xc1,0xb9,0xf4, 0xff,0xae,0xe3,0xd8,0x4d,0xe6,0x63,0x02,0x80,0xc5, 0xf1,0xf7,0xe5,0x14,0x50,0xf6,0xfc,0x90,0x88,0x03, 0x77,0xc4,0x40,0xee,0xe0,0xc3,0x85,0x77,0xc5,0x0d, 0x50,0x53,0xff,0xf1,0x47,0xb2,0xc1,0x4e,0x39, }; const uint8_t key_1027_public_exponent[]={ 0x01,0x00,0x01, }; const uint8_t key_1027_private_exponent[]={ 0x01,0x1f,0x2c,0xad,0x86,0xf3,0x33,0x7b,0x1f,0x8b, 0xbc,0xe2,0x34,0x27,0xc9,0xb6,0xc2,0x81,0xad,0x51, 0x5a,0x3a,0xf6,0xee,0x53,0x00,0xa8,0xd7,0x93,0xfd, 0xee,0xbb,0xfd,0x58,0x25,0xf6,0x7e,0xc8,0x33,0x8c, 0xe0,0xd2,0x6b,0x79,0xe0,0x9e,0x3b,0xeb,0x4d,0x28, 0xd1,0x4c,0x2b,0x23,0xc6,0xd9,0x8b,0xd9,0xca,0x88, 0xc0,0x00,0xc0,0xfb,0x81,0x0d,0x46,0x05,0xbd,0x6a, 0xa8,0x8e,0x3a,0xda,0xcc,0x87,0x29,0xc0,0xe8,0xa0, 0x3a,0x90,0x62,0xed,0x46,0x2f,0xed,0xe7,0xc5,0xdc, 0xbe,0x5b,0x6e,0xcc,0x0d,0x2c,0x5b,0x96,0x01,0xde, 0xa3,0x8b,0x6c,0x63,0xcb,0x78,0xa8,0x52,0x53,0x4b, 0x49,0x03,0x57,0xc9,0xbb,0xe7,0xea,0x39,0x68,0xf8, 0x00,0x75,0x96,0xf3,0xdd,0xf0,0x10,0xd2,0x71, }; const uint8_t key_1027_exponent1 []={ 0x03,0xa0,0xfa,0x70,0xbe,0xc7,0x54,0xcb,0xa9,0xce, 0x93,0xa8,0x54,0x5d,0xed,0x01,0xc4,0x6e,0xf5,0x65, 0x83,0x57,0x46,0x7a,0xeb,0xaf,0x7c,0x4c,0xef,0x2a, 0x14,0x65,0x87,0xfd,0xbf,0x5a,0xf3,0xc1,0x41,0xde, 0x9e,0x02,0x69,0xfd,0x44,0xd5,0x81,0x11,0xd7,0xf3, 0x52,0x3c,0xeb,0xa6,0x6e,0xe7,0x88,0x96,0xda,0x56, 0xae,0xc5,0x64,0x69,0x29, }; const uint8_t key_1027_exponent2 []={ 0x75,0x37,0xf9,0x1b,0xa6,0x71,0x0e,0x5b,0x0f,0x34, 0xda,0x19,0x88,0x52,0x84,0x65,0x25,0xbd,0x9b,0xf0, 0xe3,0x0d,0x65,0xcf,0xb6,0xd4,0xe8,0x99,0x99,0xa1, 0xd0,0xc6,0xa6,0x6c,0x3f,0xce,0x7d,0x79,0x1b,0x6a, 0xa3,0x7e,0xed,0xe8,0x47,0xb6,0x89,0xd3,0x8a,0xa3, 0xce,0x4c,0x26,0x8f,0x12,0xbc,0x63,0xeb,0x0a,0xb1, 0x5e,0xff,0xb4,0x35, }; const uint8_t key_1027_coefficient []={ 0x04,0x0b,0x4e,0x71,0x30,0x9b,0xa2,0x68,0x9a,0x83, 0xe1,0x64,0xf3,0x37,0x17,0x4d,0x5f,0xfd,0x1e,0x98, 0xcf,0x44,0x9b,0xbc,0x49,0x67,0x93,0x1a,0x2c,0xb2, 0x00,0x6f,0x04,0x7d,0xa0,0xc1,0x0e,0xce,0xbc,0xfb, 0x6d,0xe8,0xd0,0x14,0xf7,0x8c,0xca,0x76,0x1e,0xa7, 0x3f,0xf9,0xc3,0x2b,0xfa,0x10,0x0f,0x8e,0xd2,0xcc, 0xda,0xb4,0xe2,0x48,0xb7, }; // Define the key #define CCRSA_TEST_KEY_GOOD 0 #define CCRSA_TEST_KEY_BAD_PUBLIC 1 #define CCRSA_TEST_KEY_BAD_PRIVATE 2 #define CCRSA_TEST_KEY_BAD_PRIVATE_PUBLIC_MISMATCH 3 #define CCRSA_TEST_KEY_P_AND_Q_GAP 4 #define CCRSA_TEST_KEY_WRONG_INDEX -1 #define CCRSA_TEST_KEY_NOT_ENOUGH_MEMORY -2 typedef struct ccrsa_test_key_t { const uint8_t *modulus; size_t size_modulus; const uint32_t publicExponent; const uint8_t *privateExponent; size_t size_privateExponent; const uint8_t *prime1; size_t size_prime1; const uint8_t *prime2; size_t size_prime2; const uint8_t *exponent1; size_t size_exponent1; const uint8_t *exponent2; size_t size_exponent2; const uint8_t *coefficient; size_t size_coefficient; int key_type; } ccrsa_test_key; #define array(x) x,sizeof(x) const uint8_t one[]={1}; const ccrsa_test_key rsa_key_list[] = { // ====== GOOD KEYS ======= // 0 {array(key_0_modulus),key_0_publicExponent,array(key_0_privateExponent),array(key_0_prime1),array(key_0_prime2),array(key_0_exponent1),array(key_0_exponent2),array(key_0_coefficient),CCRSA_TEST_KEY_GOOD}, // 1 {array(key_1_1024_modulus),key_1_1024_publicExponent,array(key_1_1024_privateExponent),array(key_1_1024_prime1),array(key_1_1024_prime2),array(key_1_1024_exponent1),array(key_1_1024_exponent2),array(key_1_1024_coefficient),CCRSA_TEST_KEY_GOOD}, // 2 {array(key_1_2048_modulus),key_1_2048_publicExponent,array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(key_1_2048_exponent1),array(key_1_2048_exponent2),array(key_1_2048_coefficient),CCRSA_TEST_KEY_GOOD}, // 3 {array(key_1_2048_modulus),key_1_2048_publicExponent,array(key_1_2048_privateExponent),array(key_1_2048_prime2),array(key_1_2048_prime1),array(key_1_2048_exponent2),array(key_1_2048_exponent1),array(key_1_2048_coefficient_inv),CCRSA_TEST_KEY_GOOD}, // ====== BAD KEYS ======= // 4 - Not supported ( size(prime1) > size(prime2)) {array(key_1_1024_modulus),key_1_1024_publicExponent,array(key_1_1024_privateExponent),array(key_1_1024_prime2),array(key_1_1024_prime1),array(key_1_1024_exponent2),array(key_1_1024_exponent1),array(key_1_1024_coefficient_inv),CCRSA_TEST_KEY_BAD_PRIVATE}, // 5 - Not supported ( publicExponent == 1 ) {array(key_1_2048_modulus),1,array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(key_1_2048_exponent1),array(key_1_2048_exponent2),array(key_1_2048_coefficient),CCRSA_TEST_KEY_BAD_PUBLIC}, // 6 - Not supported ( publicModulus == 0 ) {array(key_2048_all_zeroes),key_1_2048_publicExponent,array(key_1_2048_privateExponent),array(key_1_2048_prime2),array(key_1_2048_prime1),array(key_1_2048_exponent2),array(key_1_2048_exponent1),array(key_1_2048_coefficient_inv),CCRSA_TEST_KEY_BAD_PUBLIC}, // 7 - Not supported ( exponent1 == 1 ) {array(key_1_2048_modulus),key_1_2048_publicExponent,array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(one),array(key_1_2048_exponent2),array(key_1_2048_coefficient),CCRSA_TEST_KEY_BAD_PRIVATE}, // 8 - Not supported ( exponent2 == 1 ) {array(key_1_2048_modulus),key_1_2048_publicExponent,array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(key_1_2048_exponent1),array(one),array(key_1_2048_coefficient),CCRSA_TEST_KEY_BAD_PRIVATE}, // 9 - Public key does not match the private key {array(key_1_1024_modulus),65539,array(key_1_1024_privateExponent),array(key_1_1024_prime1),array(key_1_1024_prime2),array(key_1_1024_exponent1),array(key_1_1024_exponent2),array(key_1_1024_coefficient),CCRSA_TEST_KEY_BAD_PRIVATE_PUBLIC_MISMATCH}, }; typedef struct ccrsa_test_makekey_t { const uint8_t *modulus; size_t size_modulus; const uint8_t *publicExponent; size_t size_publicExponent; const uint8_t *privateExponent; size_t size_privateExponent; const uint8_t *prime1; size_t size_prime1; const uint8_t *prime2; size_t size_prime2; const uint8_t *exponent1; size_t size_exponent1; const uint8_t *exponent2; size_t size_exponent2; const uint8_t *coefficient; size_t size_coefficient; int key_type; } ccrsa_test_makekey; uint8_t public_e[]={0x01,0x00,0x01}; size_t public_e_length = 3; const ccrsa_test_makekey rsa_makepriv_key_list[] = { // ====== GOOD KEYS ======= // 0 {array(key_0_modulus),array(public_e),array(key_0_privateExponent),array(key_0_prime1),array(key_0_prime2),array(key_0_exponent1),array(key_0_exponent2),array(key_0_coefficient),CCRSA_TEST_KEY_GOOD}, // 1 {array(key_1_1024_modulus),array(public_e),array(key_1_1024_privateExponent),array(key_1_1024_prime1),array(key_1_1024_prime2),array(key_1_1024_exponent1),array(key_1_1024_exponent2),array(key_1_1024_coefficient),CCRSA_TEST_KEY_GOOD}, // 2 {array(key_1_2048_modulus),array(public_e),array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(key_1_2048_exponent1),array(key_1_2048_exponent2),array(key_1_2048_coefficient),CCRSA_TEST_KEY_GOOD}, // 3 {array(key_1_2048_modulus),array(public_e),array(key_1_2048_privateExponent),array(key_1_2048_prime2),array(key_1_2048_prime1),array(key_1_2048_exponent2),array(key_1_2048_exponent1),array(key_1_2048_coefficient_inv),CCRSA_TEST_KEY_GOOD}, // 4 - {array(key_1_1024_modulus),array(public_e),array(key_1_1024_privateExponent),array(key_1_1024_prime2),array(key_1_1024_prime1),array(key_1_1024_exponent2),array(key_1_1024_exponent1),array(key_1_1024_coefficient_inv),CCRSA_TEST_KEY_GOOD}, // 5 - {array(key_1026_modulus),array(key_1026_public_exponent),array(key_1026_private_exponent),array(key_1026_prime_1),array(key_1026_prime_2),array(key_1026_exponent1),array(key_1026_exponent2),array(key_1026_coefficient),CCRSA_TEST_KEY_GOOD}, // ====== BAD KEYS ======= // 6 - Not supported ( publicExponent == 1 ) {array(key_1_2048_modulus), array(one), array(key_1_2048_privateExponent),array(key_1_2048_prime1),array(key_1_2048_prime2),array(key_1_2048_exponent1),array(key_1_2048_exponent2),array(key_1_2048_coefficient),CCRSA_TEST_KEY_BAD_PUBLIC}, // 7 - Not supported ( gap betwene P' and Q's bitlength is greater than 2) {array(key_1027_modulus),array(key_1027_public_exponent),array(key_1027_private_exponent),array(key_1027_prime_1),array(key_1027_prime_2),array(key_1027_exponent1),array(key_1027_exponent2),array(key_1027_coefficient), CCRSA_TEST_KEY_P_AND_Q_GAP}, }; // Initialize a fullkey structure "fullkey" from the key at "index" in "rsa_key_list" static int ccrsa_test_setkey(ccrsa_full_ctx_t fk, size_t fk_bit_size, size_t index) { if (index>=sizeof(rsa_key_list)/sizeof(rsa_key_list[0])) return CCRSA_TEST_KEY_WRONG_INDEX; cc_size n = ccn_nof_size(rsa_key_list[index].size_modulus); cc_unit tmp_u[n]; ccn_read_uint(n,tmp_u,rsa_key_list[index].size_modulus,rsa_key_list[index].modulus); if (n>ccn_nof(fk_bit_size)) return CCRSA_TEST_KEY_NOT_ENOUGH_MEMORY; // Full key is too small for this key ccrsa_ctx_n(fk) = n; ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); // p ccn_read_uint(n,tmp_u,rsa_key_list[index].size_prime1,rsa_key_list[index].prime1); CCZP_N(ccrsa_ctx_private_zp(fk)) = ccn_n(n,tmp_u); // q ccn_read_uint(n,tmp_u,rsa_key_list[index].size_prime2,rsa_key_list[index].prime2); CCZP_N(ccrsa_ctx_private_zq(fk)) = ccn_n(n,tmp_u); // Rest of it ccn_seti(n, ccrsa_ctx_e(pubk), rsa_key_list[index].publicExponent); ccn_read_uint(n,CCZP_PRIME(ccrsa_ctx_zm(pubk)),rsa_key_list[index].size_modulus,rsa_key_list[index].modulus); ccn_read_uint(n,ccrsa_ctx_d(fk),rsa_key_list[index].size_privateExponent,rsa_key_list[index].privateExponent); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)),CCZP_PRIME(ccrsa_ctx_private_zp(fk)),rsa_key_list[index].size_prime1,rsa_key_list[index].prime1); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)),ccrsa_ctx_private_dp(fk),rsa_key_list[index].size_exponent1,rsa_key_list[index].exponent1); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)),CCZP_PRIME(ccrsa_ctx_private_zq(fk)),rsa_key_list[index].size_prime2,rsa_key_list[index].prime2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)),ccrsa_ctx_private_dq(fk),rsa_key_list[index].size_exponent2,rsa_key_list[index].exponent2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)),ccrsa_ctx_private_qinv(fk),rsa_key_list[index].size_coefficient,rsa_key_list[index].coefficient); // Perform initialization cczp_init(ccrsa_ctx_private_zp(fk)); cczp_init(ccrsa_ctx_private_zq(fk)); cczp_init(ccrsa_ctx_zm(pubk)); return rsa_key_list[index].key_type; } //============================================================================== // Keys //============================================================================== #define RSA_MAX_BIT_SIZE 4096 static int test_sample_pkcs1v15(void) { byteBuffer digest=hexStringToBytes("2812fd163b700eaad52a82c2d330eb1d2b23c1db"); byteBuffer nullOIDdigest=hexStringToBytes("3021300906052b0e03021a050004142812fd163b700eaad52a82c2d330eb1d2b23c1db"); uint8_t fault_canary[sizeof(CCRSA_PKCS1_FAULT_CANARY)]; const unsigned char *oid=CC_DIGEST_OID_SHA1; uint32_t status=0,test_step=0; byteBuffer encoded_message=hexStringToBytes("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004142812fd163b700eaad52a82c2d330eb1d2b23c1db"); byteBuffer expected_sig=hexStringToBytes("203b16fdecf3989a60d161914b60c0459ff3f4925ca1298c1514f97a12086214647e7ff1162ea1b22e1a0133a60fcd9a6bd2efc91de7561c6c67e7b9f1b945cf51242c4169d84c29a1231decf292fe44b972090ebb057a10425f26962e755d76bee595e803d8f79b423af780a97b9d149f84d24a6623642e16ae013ec78f10c6"); ccrsa_full_ctx_decl(ccn_sizeof(RSA_MAX_BIT_SIZE), fk); int rc = ccrsa_test_setkey(fk,RSA_MAX_BIT_SIZE,1); ok(rc==CCRSA_TEST_KEY_GOOD,"Initialize key"); if(rc!=CCRSA_TEST_KEY_GOOD){ free(expected_sig); free(encoded_message); free(digest); return -1; } ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); cc_size n = ccrsa_ctx_n(fk); cc_unit tmp_u[n]; uint8_t result[ccn_sizeof_n(n)]; bool valid; // Convert in uint ccn_zero(n, tmp_u); ccn_read_uint(n,tmp_u,encoded_message->len,encoded_message->bytes); //========================================================================== // KAT for ccrsa_verify_pkcs1v15 //========================================================================== // "Sign" if (0==ccrsa_priv_crypt_blinded(global_test_rng, fk, tmp_u, tmp_u)) status|=1<len, result); if (0==memcmp(result,expected_sig->bytes,expected_sig->len)) status|=1<len, digest->bytes, expected_sig->len,expected_sig->bytes, &valid) && (valid==true)) { status|=1<len, digest->bytes, expected_sig->len, expected_sig->bytes, NULL) == CCERR_VALID_SIGNATURE) { status |= 1 << test_step; } test_step++; if (ccrsa_verify_pkcs1v15_digest(pubk, oid, digest->len, digest->bytes, expected_sig->len, expected_sig->bytes, fault_canary) == CCERR_VALID_SIGNATURE) { status |= 1 << test_step; } test_step++; if (memcmp(CCRSA_PKCS1_FAULT_CANARY, fault_canary, sizeof(CCRSA_PKCS1_FAULT_CANARY)) == 0) { status |= 1 << test_step; } test_step++; // Without OID if (0==ccrsa_verify_pkcs1v15(pubk, NULL, nullOIDdigest->len, nullOIDdigest->bytes, expected_sig->len,expected_sig->bytes, &valid) && (valid==true)) status|=1<len, digest->bytes, &result_size,result)) status|=1<len) && (0==memcmp(result,expected_sig->bytes,expected_sig->len))) status|=1<len, nullOIDdigest->bytes, &result_size,result)) status|=1<len) && 0==memcmp(result,expected_sig->bytes,expected_sig->len)) status|=1<= 0) { int expected_result = 0; cc_unit unit_tmp[ccn_nof(keysize)]; uint8_t *byte_tmp = (uint8_t *)unit_tmp; ccn_seti(ccn_nof(keysize), unit_tmp, 2); // ccrsa_dump_full_key(full_key); modulus_size = CC_BITLEN_TO_BYTELEN(ccrsa_pubkeylength(ccrsa_ctx_public(full_key))); output_size = modulus_size; pub_key = ccrsa_ctx_public(full_key); if (verbose) diag("Testing key %d, %s (%d)", i - 1, (key_type > 0) ? "Invalid key, expect assert" : "valid", key_type); switch (key_type) { case CCRSA_TEST_KEY_GOOD: // ============================================================= // Good key, test all round trips // ============================================================= for (int j = 0; j < RSA_KNOWN_KEY_STRESS; j++) test_rsa_roundtrip(full_key, TEST_KEY_SANITY); break; case CCRSA_TEST_KEY_BAD_PUBLIC: // ============================================================= // Test that public key operations fail as expected // ============================================================= // Encryptions is(ccrsa_pub_crypt(pub_key, unit_tmp, unit_tmp), CCRSA_KEY_ERROR, "Key ok"); is(ccrsa_encrypt_eme_pkcs1v15(pub_key, rng, &output_size, byte_tmp, modulus_size - 16, byte_tmp), CCRSA_KEY_ERROR, "Key ok"); output_size = modulus_size; is(ccrsa_encrypt_oaep( pub_key, di, rng, &output_size, byte_tmp, modulus_size - (2 * di->output_size + 2), byte_tmp, 0, NULL), CCRSA_KEY_ERROR, "Key ok"); // Verifications valid = true; is(ccrsa_verify_pkcs1v15(pub_key, di->oid, di->output_size, byte_tmp, modulus_size, byte_tmp, &valid), CCRSA_KEY_ERROR, "Key ok"); is(valid, false, "Fail close"); valid = true; is(ccrsa_verify_pss(pub_key, di, di, di->output_size, byte_tmp, modulus_size, byte_tmp, 20, &valid), CCRSA_KEY_ERROR, "Key ok"); is(valid, false, "Fail close"); break; case CCRSA_TEST_KEY_BAD_PRIVATE: expected_result = CCRSA_KEY_ERROR; case CCRSA_TEST_KEY_BAD_PRIVATE_PUBLIC_MISMATCH: if (expected_result == 0) { expected_result = CCRSA_PRIVATE_OP_ERROR; } // ============================================================= // Test that private key operations fail as expected // ============================================================= // Decryptions is(ccrsa_priv_crypt_blinded(rng, full_key, unit_tmp, unit_tmp), expected_result, "Key ok"); is(ccrsa_decrypt_eme_pkcs1v15_blinded(rng, full_key, &output_size, byte_tmp, modulus_size, byte_tmp), expected_result, "Key ok"); output_size = modulus_size; is(ccrsa_decrypt_oaep_blinded(rng, full_key, di, &output_size, byte_tmp, modulus_size, byte_tmp, 0, NULL), expected_result, "Key ok"); // Signature is(ccrsa_sign_pkcs1v15_blinded(rng, full_key, di->oid, di->output_size, byte_tmp, &modulus_size, byte_tmp), expected_result, "Key ok"); is(ccrsa_sign_pss_blinded(rng, full_key, di, di, 20, rng, di->output_size, byte_tmp, &modulus_size, byte_tmp), expected_result, "Key ok"); break; default: // ============================================================= // Unexpected error // ============================================================= fail("Unexpected key setup error"); break; } } is(key_type, CCRSA_TEST_KEY_WRONG_INDEX, "Expected termination"); return 0; } // return 0 iff success static int RSAStd_Gen_Test(size_t keysize, uint32_t exponent) { #if CC_DISABLE_RSAKEYGEN (void) keysize; (void) exponent; return 0; #else ccrsa_full_ctx_decl(ccn_sizeof(keysize), full_key); uint8_t e4[4]; for(int i=0; i<4; i++) e4[3-i] = ((exponent >> (i*8)) & 0x000000ff); int status = 1; struct ccrng_state *rng = global_test_rng; is(ccrsa_generate_key(keysize, full_key, 4, e4, rng), 0, "RSA Key generation"); is(ccn_bitlen(ccrsa_ctx_n(full_key),ccrsa_ctx_m(full_key)),keysize, "RSA expected keysize"); is((status = test_rsa_roundtrip(full_key,TEST_KEY_SANITY)), 0, "RSA Round-Trip Key Tests"); return status; #endif } // Test ccrsa_make_priv using data from "rsa_key_list" static int ccrsa_test_make_priv() { // rsa_makepriv_key_list contains a number of keys we can test against. Iterate through them // load each key using ccrsa_make_priv, and ensure that the resulting key or error is as expected. for (size_t i = 0; i < CC_ARRAY_LEN(rsa_makepriv_key_list); i++) { const int keysize = 2048 + 8; // Largest key size we care about ccrsa_full_ctx_decl(ccn_sizeof(keysize), full_context); // create context to give make_priv ccrsa_full_ctx_decl(ccn_sizeof(keysize), fk); // create context to hold test data. // Retrieve the size of the modulus we're using. cc_size n = ccn_nof_size(rsa_makepriv_key_list[i].size_modulus); if (n > ccn_nof(keysize)) return CCRSA_TEST_KEY_NOT_ENOUGH_MEMORY; // create space to hold the modulus; retrieve its length and later compare that we compute correct value. cc_unit tmp_u[n]; ccn_read_uint(n, tmp_u, rsa_makepriv_key_list[i].size_modulus, rsa_makepriv_key_list[i].modulus); // Initialize context with appropriate modulus size ccrsa_ctx_n(fk) = n; ccrsa_ctx_n(full_context) = n; ccrsa_pub_ctx_t pubk = ccrsa_ctx_public(fk); // Get the lengths of p and q, so we can get the accessor functions properly setup // so we can load appropraite values later. // p ccn_read_uint(n, tmp_u, rsa_makepriv_key_list[i].size_prime1, rsa_makepriv_key_list[i].prime1); CCZP_N(ccrsa_ctx_private_zp(fk)) = ccn_n(n, tmp_u); // q (Note: ccrsa_ctx_private_zq must be called after the length of ccrsa_ctx_private_zp->n has been set) ccn_read_uint(n, tmp_u, rsa_makepriv_key_list[i].size_prime2, rsa_makepriv_key_list[i].prime2); CCZP_N(ccrsa_ctx_private_zq(fk)) = ccn_n(n, tmp_u); // Rest of it ccn_read_uint( n, ccrsa_ctx_e(pubk), rsa_makepriv_key_list[i].size_publicExponent, rsa_makepriv_key_list[i].publicExponent); ccn_read_uint(n, CCZP_PRIME(ccrsa_ctx_zm(pubk)), rsa_makepriv_key_list[i].size_modulus, rsa_makepriv_key_list[i].modulus); ccn_read_uint( n, ccrsa_ctx_d(fk), rsa_makepriv_key_list[i].size_privateExponent, rsa_makepriv_key_list[i].privateExponent); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)), CCZP_PRIME(ccrsa_ctx_private_zp(fk)), rsa_makepriv_key_list[i].size_prime1, rsa_makepriv_key_list[i].prime1); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)), ccrsa_ctx_private_dp(fk), rsa_makepriv_key_list[i].size_exponent1, rsa_makepriv_key_list[i].exponent1); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)), CCZP_PRIME(ccrsa_ctx_private_zq(fk)), rsa_makepriv_key_list[i].size_prime2, rsa_makepriv_key_list[i].prime2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)), ccrsa_ctx_private_dq(fk), rsa_makepriv_key_list[i].size_exponent2, rsa_makepriv_key_list[i].exponent2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)), ccrsa_ctx_private_qinv(fk), rsa_makepriv_key_list[i].size_coefficient, rsa_makepriv_key_list[i].coefficient); // Now make another ccrsa_full_context by passing the e, p and q; N, d, dp and dq should self-generate via ccrsa_make_priv int result_of_make_priv; result_of_make_priv = ccrsa_make_priv(full_context, rsa_makepriv_key_list[i].size_publicExponent, rsa_makepriv_key_list[i].publicExponent, rsa_makepriv_key_list[i].size_prime1, rsa_makepriv_key_list[i].prime1, rsa_makepriv_key_list[i].size_prime2, rsa_makepriv_key_list[i].prime2); // Make sure everything went as expected. switch (rsa_makepriv_key_list[i].key_type) { // case where key generation should have gone smoothly case CCRSA_TEST_KEY_GOOD: is(result_of_make_priv, 0, "Failed in call ccrsa_make_priv in ccrsa_test_make_priv on a good key"); ok_memcmp(ccrsa_ctx_e(fk), ccrsa_ctx_e(full_context), CCN_UNIT_SIZE * cczp_n(ccrsa_ctx_zm(fk)), "Comparing given vs computed e in ccrsa_test_make_priv on rsa_makepriv_key_list[%d]", i); ok_memcmp(ccrsa_ctx_d(fk), ccrsa_ctx_d(full_context), CCN_UNIT_SIZE * ccrsa_ctx_zm(fk)->n, "Comparing given vs computed d in ccrsa_test_make_priv on rsa_makepriv_key_list[%d]", i); ok_memcmp(ccrsa_ctx_zm(fk)->ccn, ccrsa_ctx_zm(full_context)->ccn, CCN_UNIT_SIZE * ccrsa_ctx_zm(fk)->n, "Comparing given vs computed zm in ccrsa_test_make_priv on rsa_makepriv_key_list[%d]", i); // Because ccrsa_make_priv will switch ordering of p and q if needed, we need to switch the order of the test cases // for comparison. if q > p in the original test vector, we re-read it into the comparison context with their orders // reverse. int swap_pq = 0; // Since ccrsa_make_priv takes p and q if (ccn_cmpn(ccn_n(ccrsa_ctx_private_zp(fk)->n, ccrsa_ctx_private_zp(fk)->ccn), ccrsa_ctx_private_zp(fk)->ccn, ccn_n(ccrsa_ctx_private_zq(fk)->n, ccrsa_ctx_private_zq(fk)->ccn), ccrsa_ctx_private_zq(fk)->ccn) < 0) { swap_pq = 1; // Set swap flag to 1, to help with debugging. cc_size swap_p_size = CCZP_N(ccrsa_ctx_private_zp(fk)); CCZP_N(ccrsa_ctx_private_zp(fk)) = CCZP_N(ccrsa_ctx_private_zq(fk)); CCZP_N(ccrsa_ctx_private_zq(fk)) = swap_p_size; ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)), CCZP_PRIME(ccrsa_ctx_private_zp(fk)), rsa_makepriv_key_list[i].size_prime2, rsa_makepriv_key_list[i].prime2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zp(fk)), ccrsa_ctx_private_dp(fk), rsa_makepriv_key_list[i].size_exponent2, rsa_makepriv_key_list[i].exponent2); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)), CCZP_PRIME(ccrsa_ctx_private_zq(fk)), rsa_makepriv_key_list[i].size_prime1, rsa_makepriv_key_list[i].prime1); ccn_read_uint(cczp_n(ccrsa_ctx_private_zq(fk)), ccrsa_ctx_private_dq(fk), rsa_makepriv_key_list[i].size_exponent1, rsa_makepriv_key_list[i].exponent1); } ok_memcmp(ccrsa_ctx_private_zp(fk)->ccn, ccrsa_ctx_private_zp(full_context)->ccn, CCN_UNIT_SIZE * cczp_n(ccrsa_ctx_private_zp(fk)), "Comparing given vs computed zp in ccrsa_test_make_priv in rsa_makepriv_key_list[%d].prime1. Value of " "swap_pq is %d", i, swap_pq); ok_memcmp(ccrsa_ctx_private_zq(fk)->ccn, ccrsa_ctx_private_zq(full_context)->ccn, CCN_UNIT_SIZE * cczp_n(ccrsa_ctx_private_zq(fk)), "Comparing given vs computed zq in ccrsa_test_make_priv in rsa_makepriv_key_list[%d].prime2. Value of " "swap_pq is %d", i, swap_pq); ok_memcmp(ccrsa_ctx_private_dp(fk), ccrsa_ctx_private_dp(full_context), CCN_UNIT_SIZE * cczp_n(ccrsa_ctx_private_zq(fk)), "Comparing given vs computed dp in ccrsa_test_make_priv. Value of swap_pq is %d", i, swap_pq); ok_memcmp(ccrsa_ctx_private_dq(fk), ccrsa_ctx_private_dq(full_context), CCN_UNIT_SIZE * cczp_n(ccrsa_ctx_private_zq(fk)), "Comparing given vs computed dq in ccrsa_test_make_priv. Value of swap_pq is %d", i, swap_pq); // Perform a full test of the generated context, to make sure it works as expected. test_rsa_roundtrip(full_context, TEST_ALL_ALGOS); break; case CCRSA_TEST_KEY_P_AND_Q_GAP: is(result_of_make_priv, CCRSA_KEYGEN_PQ_DELTA_ERROR, "Accepeted as a good key a known bad key in rsa_makepriv_key_list[%zu]", i); break; default: is(result_of_make_priv, CCRSA_INVALID_INPUT, "Accepeted as a good key a known bad key in rsa_makepriv_key_list[%zu]", i); break; } } return 0; } /* Generation of random keys */ // return 0 iff success static int RSAFIPS_Gen_Test(size_t keysize, uint32_t exponent) { cc_assert(keysize <= 4096); //for Windows debugging ccrsa_full_ctx_decl(ccn_sizeof(keysize), full_key); cc_assert(full_key != NULL);//for Windows debugging uint8_t e4[4]; for(int i=0; i<4; i++) e4[3-i] = ((exponent >> (i*8)) & 0x000000ff); int status = 1; struct ccrng_state *rng = global_test_rng; is((status = ccrsa_generate_fips186_key(keysize, full_key, 4, e4, rng, rng)),0, "RSA FIPS Key generation"); if (status) return 1; is(ccn_bitlen(ccrsa_ctx_n(full_key),ccrsa_ctx_m(full_key)),keysize, "RSA FIPS expected keysize"); is((status = test_rsa_roundtrip(full_key,TEST_ALL_ALGOS)),0, "RSA FIPS Round-Trip Key Tests"); return status; } /* Known Answer Tests */ static int RSAFIPS_Gen_KAT_Test( char *estr, char *xp1str, char *xp2str, char *xpstr, char *xq1str, char *xq2str, char *xqstr, char *pstr, char *qstr, char *mstr, char *dstr) { byteBuffer e = hexStringToBytes(estr); ccnBuffer xp1 = hexStringToCcn(xp1str); ccnBuffer xp2 = hexStringToCcn(xp2str); ccnBuffer xp = hexStringToCcn(xpstr); ccnBuffer xq1 = hexStringToCcn(xq1str); ccnBuffer xq2 = hexStringToCcn(xq2str); ccnBuffer xq = hexStringToCcn(xqstr); ccnBuffer expectedP = hexStringToCcn(pstr); ccnBuffer expectedQ = hexStringToCcn(qstr); ccnBuffer expectedM = hexStringToCcn(mstr); ccnBuffer expectedD = hexStringToCcn(dstr); int success = 1; cc_size nbits = ccn_bitlen(expectedM->len, expectedM->units); cc_size n = ccn_sizeof(nbits); ccrsa_full_ctx_decl(ccn_sizeof_n(n), full_key); struct ccrng_rsafips_test_state rng1; struct ccrng_rsafips_test_state rng2; // Rngs ccrng_rsafips_test_init(&rng1,xp1->len,xp1->units,xp2->len,xp2->units,xp->len,xp->units); ccrng_rsafips_test_init(&rng2,xq1->len,xq1->units,xq2->len,xq2->units, xq->len, xq->units); ccrng_rsafips_test_set_next(&rng1, &rng2); // Computations success&=ok((ccrsa_generate_fips186_key(nbits, full_key, e->len, e->bytes, (struct ccrng_state *)&rng1, global_test_rng)==0), "RSA FIPS Key generation"); success&=ok((ccn_bitlen(ccrsa_ctx_n(full_key),ccrsa_ctx_m(full_key))==nbits), "RSA FIPS expected keysize"); /* if ( (ccn_cmp(expectedQ->len,cczp_prime((((full_key)).zp)), expectedQ->units)==0) && (ccn_cmp(expectedP->len,cczp_prime(((cczp_t)(((full_key)).zp.zp->ccn + 2 * (((full_key)).zp).zp->n + 1))), expectedP->units)==0)) { printf("Swapped P and Q\n"); } */ // Verify results if ( (ccn_cmp(expectedQ->len,cczp_prime(ccrsa_ctx_private_zp(full_key)), expectedQ->units)==0) && (ccn_cmp(expectedP->len,cczp_prime(ccrsa_ctx_private_zq(full_key)), expectedP->units)==0)) { printf("Swapped P and Q\n"); } success&=ok_ccn_cmp(expectedP->len,cczp_prime(ccrsa_ctx_private_zp(full_key)), expectedP->units, "p is built correctly"); success&=ok_ccn_cmp(expectedQ->len,cczp_prime(ccrsa_ctx_private_zq(full_key)), expectedQ->units, "q is built correctly"); success&=ok_ccn_cmp(expectedD->len,ccrsa_ctx_d(full_key), expectedD->units, "d is built correctly"); success&=ok_ccn_cmp(expectedM->len,ccrsa_ctx_m(full_key), expectedM->units, "m is built correctly"); if (!success) goto errout; // Skip roundtrip if make failed success&=is(test_rsa_roundtrip(full_key,TEST_ALL_ALGOS),0, "RSA Round-Trip Key Tests"); errout: free(e);free(xp1); free(xp2); free(xp); free(xq1); free(xq2); free(xq); free(expectedP); free(expectedQ); free(expectedM); free(expectedD); if (success) return 0; return 1; // Error } /* Negative tests */ static int RSAFIPS_Negative_Test(void) { cc_size keysize=2048; ccrsa_full_ctx_decl(ccn_sizeof(keysize), full_key); uint8_t e1[4]={0,0,0,1}; uint8_t e_even[4]={0,1,0,2}; uint8_t e_small[4]={0,0,0xff,0xff}; // 2^16-1 uint8_t e_large[33]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; // 2^256+1 uint8_t e65537[4]={0,1,0,1}; uint8_t seq[3]={0x00,0xff,0xba}; struct ccrng_sequence_state rng_seq; struct ccrng_rsafips_test_state rng1; struct ccrng_rsafips_test_state rng2; struct ccrng_state *trng=global_test_rng; // The keysize for generation is smaller than the required size ok((ccrsa_generate_fips186_key(511, full_key, 4, e65537, trng, trng)!=0), "Fail for small size"); // The keysize for generation is larger than the allowed size ok((ccrsa_generate_fips186_key(8193, full_key, 4, e65537, trng, trng)!=0), "Fail for large size"); // Exponent is one while it must be >1 ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e1, trng, trng)!=0), "Fail for exponent=1"); // Exponent is one while it must be >1 ok((ccrsa_generate_key(keysize, full_key, 4, e1, trng)!=0), "Fail for exponent=1"); // Exponent is one while it must be >2^16 ok((ccrsa_generate_fips186_key(keysize, full_key, sizeof(e_small), e_small, trng, trng)!=0), "Fail for small exponent size"); // Exponent is one while it must be <2^256 ok((ccrsa_generate_fips186_key(keysize, full_key, sizeof(e_large), e_large, trng, trng)!=0), "Fail for large exponent size"); // Exponent is even while it must be odd ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e_even, trng, trng)!=0), "Fail for even exponent"); // Exponent is even while it must be odd ok((ccrsa_generate_key(keysize, full_key, 4, e_even, trng)!=0), "Fail for even exponent"); // Rng fails ccrng_sequence_init(&rng_seq, 0, NULL); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng_seq, trng)!=0), "Fail for bad RNG P"); // Rng single values ccrng_sequence_init(&rng_seq, 1, &seq[0]); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng_seq, trng)!=0), "RNG returns all 0x00"); ccrng_sequence_init(&rng_seq, 1, &seq[1]); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng_seq, trng)!=0), "RNG returns all 0xff"); // Check identical P&Q are rejected ccrng_sequence_init(&rng_seq, 1, &seq[2]); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng_seq, trng)!=0), "P&Q are seeded with 0xba"); // P&Q and Xp,Xq delta too small, using a 2048 key. { //cc_size n=ccn_nof(nbits); ccnBuffer ccn_xp1 = hexStringToCcn("1747cbbd8b16c4dbc259e53b8a5c7db1b9f5"); ccnBuffer ccn_xp2 = hexStringToCcn("18946d3a6f5e3e088446dd0e04aa62bc87e8"); ccnBuffer ccn_xp = hexStringToCcn("6fccd146d52a5b4adda4a45a45f2eabb41da13fe6de477dad87d361d69c2cbb79640e76ac7c28abbce096dbf2e638b2053fc39c503bfcdc64d0ae2d7d818bb984896f115a76a8edad23e996b536856f808c717999dbb3955c4213b001a6d9722ce8d69e6b57e103a2f24765da3a2a413254b0c388172ad2f2cd623a9ce296c99"); cc_unit xq1[ccn_xp1->len]; cc_unit xq2[ccn_xp2->len]; cc_unit xq[ccn_xp->len]; cc_unit tmp[ccn_xp->len]; // |Xp-Xq|=2^(nbits/2-100) => fail // 2.q1.q2 > 2.r1.r2 so that |p-q|>2^(nbits/2-100) ccn_zero(ccn_xp->len,tmp); ccn_set_bit(tmp,((keysize/2)-100),1); ccn_add(ccn_xp->len,xq,ccn_xp->units,tmp); ccn_set(ccn_xp1->len,xq1,ccn_xp1->units); // xq1=xp1 ccn_add1(ccn_xp2->len,xq2,ccn_xp2->units,((cc_unit)1)<<31); // xq2=xp1+2^31 ccrng_rsafips_test_init(&rng1,ccn_xp1->len,ccn_xp1->units,ccn_xp2->len,ccn_xp2->units,ccn_xp->len,ccn_xp->units); ccrng_rsafips_test_init(&rng2,ccn_xp1->len,xq1,ccn_xp2->len,xq2, ccn_xp->len, xq); ccrng_rsafips_test_set_next(&rng1, &rng2); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng1, trng)!=0), "RSA FIPS Key generation"); ccrng_rsafips_test_init(&rng1,ccn_xp1->len,ccn_xp1->units,ccn_xp2->len,ccn_xp2->units,ccn_xp->len,ccn_xp->units); ccrng_rsafips_test_init(&rng2,ccn_xp1->len,xq1,ccn_xp2->len,xq2, ccn_xp->len, xq); ccrng_rsafips_test_set_next(&rng1, &rng2); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng1, trng)!=0), "RSA FIPS Key generation"); // |Xp-Xq|=2^(nbits/2-100)+2 => pass // 2.q1.q2 > 2.r1.r2 so that |p-q|>2^(nbits/2-100) ccn_zero(ccn_xp->len,tmp); ccn_set_bit(tmp,((keysize/2)-100),1); ccn_set_bit(tmp,(cc_unit)1,1); ccn_add(ccn_xp->len,xq,ccn_xp->units,tmp); ccn_zero(ccn_xp1->len,xq1); ccn_zero(ccn_xp2->len,xq2); ccrng_rsafips_test_init(&rng1,ccn_xp1->len,xq1,ccn_xp2->len,xq2,ccn_xp->len,ccn_xp->units); ccrng_rsafips_test_init(&rng2,ccn_xp1->len,ccn_xp1->units,ccn_xp2->len,ccn_xp2->units, ccn_xp->len, xq); ccrng_rsafips_test_set_next(&rng1, &rng2); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng1, trng)!=0), "RSA FIPS Key generation"); ccrng_rsafips_test_init(&rng1,ccn_xp1->len,xq1,ccn_xp2->len,xq2,ccn_xp->len,ccn_xp->units); ccrng_rsafips_test_init(&rng2,ccn_xp1->len,ccn_xp1->units,ccn_xp2->len,ccn_xp2->units, ccn_xp->len, xq); ccrng_rsafips_test_set_next(&rng1, &rng2); ok((ccrsa_generate_fips186_key(keysize, full_key, 4, e65537, (struct ccrng_state *)&rng1, trng)!=0), "RSA FIPS Key generation"); // Free free(ccn_xp1); free(ccn_xp2); free(ccn_xp); } // Close rng fd. return 0; } /* Known answer tests with construct function */ static int RSAFIPS_Make_Test(cc_unit e, char *xp1str, char *xp2str, char *xpstr, char *xq1str, char *xq2str, char *xqstr, char *pstr, char *qstr, char *mstr, char *dstr) { ccnBuffer xp1 = hexStringToCcn(xp1str); ccnBuffer xp2 = hexStringToCcn(xp2str); ccnBuffer xp = hexStringToCcn(xpstr); ccnBuffer xq1 = hexStringToCcn(xq1str); ccnBuffer xq2 = hexStringToCcn(xq2str); ccnBuffer xq = hexStringToCcn(xqstr); ccnBuffer expectedP = hexStringToCcn(pstr); ccnBuffer expectedQ = hexStringToCcn(qstr); ccnBuffer expectedM = hexStringToCcn(mstr); ccnBuffer expectedD = hexStringToCcn(dstr); ccnBuffer retP = mallocCcnBuffer(MAXKEYSPACE); ccnBuffer retQ = mallocCcnBuffer(MAXKEYSPACE); ccnBuffer retM = mallocCcnBuffer(MAXKEYSPACE); ccnBuffer retD = mallocCcnBuffer(MAXKEYSPACE); int success = 1; cc_size n = xp->len + xq->len; cc_size nbits = ccn_bitsof_n(n); ccrsa_full_ctx_decl(ccn_sizeof(nbits), full_key); success&=is(ccrsa_make_fips186_key(nbits, 1, &e, xp1->len, xp1->units, xp2->len, xp2->units, xp->len, xp->units, xq1->len, xq1->units, xq2->len, xq2->units, xq->len, xq->units, full_key, &retP->len, retP->units, &retQ->len, retQ->units, &retM->len, retM->units, &retD->len, retD->units),0, "ccrsa_make_fips186_key"); if(ccnAreEqual(retP, expectedQ) && ccnAreEqual(retQ, expectedP)) { ccnBuffer tmp = retP; retP = retQ; retQ = tmp; printf("Swapped P and Q\n"); } success&=ok_ccn_cmp(expectedP->len,retP->units, expectedP->units, "p is built correctly"); success&=ok_ccn_cmp(expectedQ->len,retQ->units, expectedQ->units, "q is built correctly"); success&=ok_ccn_cmp(expectedD->len,retD->units, expectedD->units, "d is built correctly"); success&=ok_ccn_cmp(expectedM->len,retM->units, expectedM->units, "m is built correctly"); if (!success) goto errout; // Skip roundtrip if make failed success&=is(test_rsa_roundtrip(full_key,TEST_KEY_SANITY),0, "RSA Round-Trip Key Tests"); errout: free(retP); free(retQ); free(retD); free(retM); free(xp1); free(xp2); free(xp); free(xq1); free(xq2); free(xq); free(expectedP); free(expectedQ); free(expectedM); free(expectedD); if (success) return 0; return 1; // Error } // Der Public key for EFI static int test_import_der_pub_key(void) { uint8_t foo[256]; int i; for(i=0; i<256; i++) foo[i] = (uint8_t)i; static uint8_t derbuf[] = { 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0xcd, 0xd7, 0xaf, 0xeb, 0x44, 0xd6, 0xa2, 0xe4, 0xe4, 0x4d, 0xb8, 0xc8, 0xd5, 0x80, 0x51, 0xc1, 0x12, 0xe1, 0xc2, 0x0c, 0xc6, 0x89, 0x29, 0x3a, 0xe9, 0x6d, 0x7e, 0x7d, 0x9d, 0xc3, 0x5a, 0xaf, 0xce, 0xdc, 0x1e, 0x92, 0x28, 0xbe, 0x00, 0x34, 0x05, 0xc8, 0x19, 0x4f, 0x7c, 0x23, 0x00, 0x3d, 0x7b, 0xdb, 0x80, 0xd1, 0x82, 0xb9, 0xca, 0xb4, 0xe4, 0x01, 0x43, 0xdc, 0x11, 0xd3, 0x20, 0xec, 0xd8, 0x44, 0xd6, 0xa8, 0x7e, 0xa7, 0xa3, 0xc2, 0x85, 0x61, 0xff, 0xd4, 0x88, 0x8e, 0x40, 0x4b, 0x1c, 0xe9, 0x2f, 0x5e, 0x48, 0x26, 0x46, 0x79, 0x65, 0xf4, 0x4f, 0x52, 0x04, 0x09, 0x0b, 0x1a, 0x05, 0x27, 0x18, 0xe9, 0x22, 0x6d, 0x10, 0xa6, 0x4b, 0xe3, 0x7a, 0x4b, 0x32, 0x8d, 0x65, 0xbf, 0x1c, 0x8d, 0x24, 0x9c, 0x12, 0xfe, 0xd3, 0xc9, 0xd6, 0x3a, 0xb2, 0xca, 0x50, 0xab, 0x37, 0x56, 0x79, 0x97, 0x79, 0xe6, 0xed, 0xf8, 0x3a, 0xc6, 0xf7, 0xec, 0x4d, 0x33, 0x9a, 0x63, 0x9c, 0xc9, 0x14, 0x7d, 0x09, 0x41, 0xe2, 0x07, 0x91, 0x1d, 0xf6, 0xe8, 0x3f, 0xe5, 0x47, 0x26, 0x6e, 0x4d, 0x20, 0x6c, 0x9e, 0x21, 0x60, 0xa0, 0xf6, 0xc8, 0x73, 0xc8, 0xa5, 0x3f, 0xbf, 0x74, 0xd3, 0x2c, 0xc5, 0xce, 0xb0, 0x71, 0xa2, 0x11, 0xee, 0xe2, 0x88, 0x43, 0x87, 0x02, 0x96, 0xe0, 0x76, 0xcb, 0x45, 0x2f, 0xe2, 0xe6, 0x01, 0xee, 0x6e, 0xab, 0x17, 0x4a, 0x20, 0xee, 0x9e, 0x7c, 0x35, 0x81, 0xe5, 0xf4, 0x82, 0x74, 0xbf, 0xe4, 0x15, 0x1e, 0x2c, 0xf7, 0x5c, 0xf6, 0x3a, 0x14, 0x16, 0xcd, 0x1a, 0xb2, 0x67, 0xfe, 0xbd, 0x34, 0x25, 0x56, 0xc1, 0x2c, 0xcd, 0xf5, 0xbf, 0x7f, 0xae, 0x63, 0x8f, 0xdc, 0x37, 0xac, 0x09, 0x9d, 0xb4, 0x3f, 0x7f, 0x0e, 0x3e, 0xb6, 0xa4, 0xa2, 0xdb, 0x02, 0x03, 0x01, 0x00, 0x01, }; size_t derlen = sizeof(derbuf); cc_size n = ccrsa_import_pub_n(derlen, derbuf); ok((ccn_sizeof_n(n) == ccn_sizeof(2048)), "size is correct"); ccrsa_pub_ctx_decl(ccn_sizeof_n(n), pubkey); ccrsa_ctx_n(pubkey) = n; if(ccrsa_import_pub(pubkey, derlen, derbuf) != 0) { printf("Internal Error importing pubkey\n"); return 0; } return 1; } // Der blob use by FastSim unsigned char derdat[] = { 0x30, 0x82, 0x01, 0xdb, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xaf, 0xb5, 0xc5, 0xc6, 0x7b, 0xc5, 0x3a, 0x34, 0x90, 0xa9, 0x54, 0xc0, 0x8f, 0xb7, 0xeb, 0xa1, 0x54, 0xd2, 0x4f, 0x22, 0xde, 0x83, 0xf5, 0x03, 0xa6, 0xc6, 0x68, 0x46, 0x9b, 0xc0, 0xb8, 0xc8, 0x6c, 0xdb, 0x26, 0xf9, 0x3c, 0x49, 0x2f, 0x02, 0xe1, 0x71, 0xdf, 0x4e, 0xf3, 0x0e, 0xc8, 0xbf, 0x22, 0x9d, 0x04, 0xcf, 0xbf, 0xa9, 0x0d, 0xff, 0x68, 0xab, 0x05, 0x6f, 0x1f, 0x12, 0x8a, 0x68, 0x62, 0xeb, 0xfe, 0xc9, 0xea, 0x9f, 0xa7, 0xfb, 0x8c, 0xba, 0xb1, 0xbd, 0x65, 0xac, 0x35, 0x9c, 0xa0, 0x33, 0xb1, 0xdd, 0xa6, 0x05, 0x36, 0xaf, 0x00, 0xa2, 0x7f, 0xbc, 0x07, 0xb2, 0xdd, 0xb5, 0xcc, 0x57, 0x5c, 0xdc, 0xc0, 0x95, 0x50, 0xe5, 0xff, 0x1f, 0x20, 0xdb, 0x59, 0x46, 0xfa, 0x47, 0xc4, 0xed, 0x12, 0x2e, 0x9e, 0x22, 0xbd, 0x95, 0xa9, 0x85, 0x59, 0xa1, 0x59, 0x3c, 0xc7, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xec, 0xbe, 0xe5, 0x5b, 0x9e, 0x7a, 0x50, 0x8a, 0x96, 0x80, 0xc8, 0xdb, 0xb0, 0xed, 0x44, 0xf2, 0xba, 0x1d, 0x5d, 0x80, 0xc1, 0xc8, 0xb3, 0xc2, 0x74, 0xde, 0xee, 0x28, 0xec, 0xdc, 0x78, 0xc8, 0x67, 0x53, 0x07, 0xf2, 0xf8, 0x75, 0x9c, 0x4c, 0xa5, 0x6c, 0x48, 0x94, 0xc8, 0xeb, 0xad, 0xd7, 0x7d, 0xd2, 0xea, 0xdf, 0x74, 0x20, 0x62, 0xc9, 0x81, 0xa8, 0x3c, 0x36, 0xb9, 0xea, 0x40, 0xfd, 0x02, 0x41, 0x00, 0xbe, 0x00, 0x19, 0x76, 0xc6, 0xb4, 0xba, 0x19, 0xd4, 0x69, 0xfa, 0x4d, 0xe2, 0xf8, 0x30, 0x27, 0x36, 0x2b, 0x4c, 0xc4, 0x34, 0xab, 0xd3, 0xd9, 0x8c, 0xd6, 0xb8, 0x0d, 0x37, 0x5e, 0x59, 0x4b, 0x76, 0x70, 0x68, 0x2b, 0x1f, 0x4c, 0x3d, 0x47, 0x5f, 0xa5, 0xb1, 0xcd, 0x74, 0x56, 0x88, 0xfe, 0x7c, 0xf8, 0x3b, 0x30, 0x6f, 0xfd, 0xc3, 0xed, 0x87, 0x3c, 0xa1, 0x53, 0x84, 0xc3, 0xd2, 0x7f, 0x02, 0x40, 0x60, 0x71, 0x9b, 0xe9, 0xe8, 0xf3, 0x97, 0x1f, 0xfe, 0x13, 0xd4, 0xbf, 0x7a, 0xa2, 0x0d, 0xf6, 0x7b, 0xcf, 0x3e, 0xaa, 0x17, 0x47, 0x75, 0xc3, 0x7f, 0xec, 0xd9, 0x44, 0x9e, 0xc9, 0x6a, 0x02, 0xe9, 0xe4, 0xaf, 0x56, 0x51, 0xd5, 0x47, 0xa9, 0x09, 0xb2, 0xc5, 0x16, 0xa7, 0x8b, 0x2b, 0x34, 0xa0, 0x33, 0x6e, 0x2f, 0x3d, 0x95, 0x7b, 0xe8, 0xef, 0x02, 0xe4, 0x14, 0xbf, 0x44, 0x28, 0xd9, 0x02, 0x40, 0x10, 0x0e, 0x2e, 0x18, 0xad, 0x5d, 0xe4, 0x43, 0xfe, 0x81, 0x1e, 0x17, 0xaa, 0xd0, 0x52, 0x31, 0x5e, 0x10, 0x76, 0xa2, 0x35, 0xd9, 0x37, 0x43, 0xb0, 0xf5, 0x0c, 0x04, 0x81, 0xe3, 0x45, 0x24, 0x6d, 0x53, 0xbe, 0x59, 0xb6, 0x81, 0x58, 0xc4, 0x49, 0x3e, 0xd5, 0x31, 0x89, 0x5d, 0x2e, 0xa2, 0x62, 0xa9, 0x0f, 0x47, 0x5e, 0x8f, 0x51, 0x19, 0x27, 0x4e, 0x66, 0x4b, 0x8a, 0x72, 0x89, 0xbd, 0x02, 0x40, 0x3e, 0x53, 0x0a, 0xf4, 0x8e, 0x75, 0xe1, 0x52, 0xc6, 0x24, 0xe9, 0xf7, 0xbb, 0xac, 0x3f, 0x22, 0x5f, 0xe8, 0xe0, 0x79, 0x35, 0xff, 0x91, 0xee, 0x22, 0x56, 0xd2, 0x00, 0x68, 0x32, 0xc4, 0xe1, 0x5f, 0xff, 0xf8, 0xb1, 0x1d, 0xee, 0xdc, 0x57, 0x81, 0xd1, 0xab, 0x8b, 0x37, 0x22, 0xe3, 0x9f, 0xd0, 0xa1, 0xc1, 0xce, 0x1d, 0xd0, 0x24, 0x23, 0xa0, 0x0e, 0xf7, 0xa6, 0xdb, 0xa3, 0xea, 0xd3 }; static int test_import_der_priv_key(void) { int status = 0; cc_size n=ccrsa_import_priv_n(sizeof(derdat), derdat); ok(!(n==0),"Import size"); ccrsa_full_ctx_decl(ccn_sizeof_n(n), tmpkey); ccrsa_ctx_n(tmpkey)=n; ok_or_fail((status = ccrsa_import_priv(tmpkey, sizeof(derdat), derdat)) == 0, "Imported Private Key"); //ccrsa_dump_full_key(tmpkey); /* manually enable for debug purposes */ ok_or_fail((status = test_rsa_roundtrip(tmpkey,TEST_KEY_SANITY)) == 0, "Can round-trip imported key"); ccrsa_full_ctx_clear(ccn_sizeof_n(n),tmpkey); return 1; // No error } static void test_recover_priv_key(void) { #if !CC_DISABLE_RSAKEYGEN const size_t keysize = 1024; const uint8_t e[] = { 0x1, 0x00, 0x01 }; ccrsa_full_ctx_decl(ccn_sizeof(keysize), fk); is(ccrsa_generate_key(keysize, fk, sizeof(e), e, global_test_rng), 0, "Generate a key"); cc_size n = ccrsa_ctx_n(fk); cczp_t zm = ccrsa_ctx_zm(fk); uint8_t m_buf[ccn_write_uint_size(n, cczp_prime(zm))]; ccn_write_uint(n, cczp_prime(zm), sizeof(m_buf), m_buf); uint8_t e_buf[ccn_write_uint_size(n, ccrsa_ctx_e(fk))]; ccn_write_uint(n, ccrsa_ctx_e(fk), sizeof(e_buf), e_buf); uint8_t d_buf[ccn_write_uint_size(n, ccrsa_ctx_d(fk))]; ccn_write_uint(n, ccrsa_ctx_d(fk), sizeof(d_buf), d_buf); ccrsa_full_ctx_decl(ccn_sizeof(keysize), fk2); is(ccrsa_recover_priv(fk2, sizeof(m_buf), m_buf, sizeof(e_buf), e_buf, sizeof(d_buf), d_buf, global_test_rng), 0, "Recover prime factors (p,q)"); is(ccrsa_recover_priv(fk2, 1, m_buf, sizeof(d_buf), d_buf, 1, d_buf, global_test_rng), CCRSA_INVALID_INPUT, "ccrsa_recover_priv() with e too large"); is(ccrsa_recover_priv(fk2, 1, m_buf, 1, e_buf, sizeof(d_buf), d_buf, global_test_rng), CCRSA_INVALID_INPUT, "ccrsa_recover_priv() with d too large"); struct { const char *m, *d; int rv; } vectors[] = { // Sanity check, should succeed. { "50a4af219805b5db", "2883beed740268d", CCERR_OK }, // An even modulus must fail. { "50a4af219805b5dc", "2883beed740268d", CCRSA_INVALID_INPUT }, // k = de - 1 must be even. { "50a4af219805b5db", "2883beed740268c", CCRSA_INVALID_INPUT }, // (e,d) are not consistent. { "50a4af219805b5db", "193c800facb0e601", CCRSA_INVALID_INPUT }, // p = q. { "fa76894d721aac91", "7685fb39", CCRSA_INVALID_INPUT }, // p is 4 bits larger than q. { "5e96b91bfdabbd45", "7a3ba71173e7251", CCRSA_INVALID_INPUT }, // d = d' + 2 * lambda { "6791c0874492e0ef", "2822953b21ac6631", CCRSA_INVALID_INPUT }, }; for (unsigned i = 0; i < CC_ARRAY_LEN(vectors); i++) { byteBuffer m_bytes = hexStringToBytes(vectors[i].m); byteBuffer d_bytes = hexStringToBytes(vectors[i].d); int rv = ccrsa_recover_priv(fk2, m_bytes->len, m_bytes->bytes, sizeof(e_buf), e_buf, d_bytes->len, d_bytes->bytes, global_test_rng); is(rv, vectors[i].rv, "ccrsa_recover_priv() test vector #%u", i); free(m_bytes); free(d_bytes); } #endif } #define SMALL_PRIME_BITS 10 #define LARGE_PRIME_BITS 512 static void test_generate_prime(void) { #if !CC_DISABLE_RSAKEYGEN cc_size n = ccn_nof(LARGE_PRIME_BITS); cc_unit p[n], exp[n]; ccn_seti(n, exp, 1); for (size_t depth = 1; depth < 10; depth++) { int result = ccrsa_generate_prime(SMALL_PRIME_BITS, p, exp, global_test_rng, global_test_rng); is(result, 0, "ccrsa_generate_prime failed to generate a prime"); result = ccrsa_generate_prime(LARGE_PRIME_BITS, p, exp, global_test_rng, global_test_rng); is(result, 0, "ccrsa_generate_prime failed to generate a prime"); } // ccrsa_generate_prime() should fail when the exponent is even. ccn_seti(n, exp, 0x10002); int rv = ccrsa_generate_prime(SMALL_PRIME_BITS, p, exp, global_test_rng, global_test_rng); is(rv, CCERR_PARAMETER, "ccrsa_generate_prime should fail"); #endif } static int test_emsa_pkcs1v15_encode_invalid_args(size_t emlen, size_t dgstlen, const uint8_t *oid) { uint8_t em[emlen]; uint8_t dgst[dgstlen]; CC_MEMSET(em, 0, emlen); CC_MEMSET(dgst, 0, dgstlen); return ccrsa_emsa_pkcs1v15_encode(emlen, em, dgstlen, dgst, oid) != CCERR_OK; } struct SizeRanges { unsigned long first; unsigned long last; }; // Test a bunch of different sizes. // Slow but these have helped catch issues. const struct SizeRanges sizesToTest[] = { { .first = 512, .last = 512 }, { .first = 1024, .last = 1088 }, { .first = 1280, .last = 1280 }, { .first = 2048, .last = 2048 }, { .first = 2056, .last = 2056 }, { .first = 3072, .last = 3072 }, { .first = 4096, .last = 4096 } }; #define nSizesToTest (sizeof(sizesToTest)/sizeof(sizesToTest[0])) #if defined(__ANDROID_API__) || defined(_WIN32) || CORECRYPTO_SIMULATE_POSIX_ENVIRONMENT #define RSA_KEYGEN_INCR_VALUE 17 #else #define RSA_KEYGEN_INCR_VALUE 1 #endif int ccrsa_tests(TM_UNUSED int argc, TM_UNUSED char *const *argv) { int verbose = 1; #if CC_DISABLE_RSAKEYGEN int stdgen = 0; int fipsgen_rand = 0; int fipsgen_kat = 0; int fipsmake_kat = 0; #elif CORECRYPTO_HACK_FOR_WINDOWS_DEVELOPMENT int stdgen = 1; int fipsgen_rand = 1; int fipsgen_kat = 0; int fipsmake_kat = 0; #else int stdgen = 1; int fipsgen_rand = 1; int fipsgen_kat = 1; int fipsmake_kat = 1; #endif plan_tests(89259); if(verbose) diag("Import DER keys"); ok(test_import_der_pub_key(), "Import RSA der public key"); ok(test_import_der_priv_key(), "Import RSA der private key"); if(verbose) diag("PKCS1 v1.5 RSA sample signature"); ok(test_sample_pkcs1v15() == 0, "Sample PKCS1 v1.5 RSA signature"); if(verbose) diag("PKCS v1.5 Known Answer Tests"); ok(test_verify_pkcs1v15_known_answer_test() == 0, "PKCS v1.5 Known Answer Tests"); if(verbose) diag("RSAPSS Known Answer Tests"); ok(test_rsa_pss_known_answer()==0, "RSAPSS Known Answer Tests"); if(verbose) diag("Test hardcoded valid and invalid keys"); ok(test_rsa_keys()==0, "Test hardcoded valid and invalid keys"); if (verbose) diag("Test EMSA PKCS#1v1.5 encoding invalid arguments"); for (size_t r = 0; r < nSizesToTest; r++) { for (size_t keysize = sizesToTest[r].first; keysize <= sizesToTest[r].last; keysize += RSA_KEYGEN_INCR_VALUE) { /* use digests close to the size of the key */ for (size_t i = 0; i < 523; i += 1) { size_t dgstlen = keysize - 10 + i; ok(test_emsa_pkcs1v15_encode_invalid_args(keysize, dgstlen, NULL), "Test EMSA PKCS#1v1.5 encoding emlen %llu dgstlen %llu null oid", keysize, dgstlen); ok(test_emsa_pkcs1v15_encode_invalid_args(keysize, dgstlen, CC_DIGEST_OID_SHA256), "Test EMSA PKCS#1v1.5 encoding emlen %llu dgstlen %llu sha256 oid", keysize, dgstlen); } /* use digests close to the size of UINT8_MAX */ for (size_t i = 230; i <= 280; i += 1) { size_t dgstlen = i; ok(test_emsa_pkcs1v15_encode_invalid_args(keysize, dgstlen, CC_DIGEST_OID_SHA256), "Test EMSA PKCS#1v1.5 encoding emlen %llu dgstlen %llu sha256 oid", keysize, dgstlen); } } } if (verbose) diag ("Test ccrsa_make_priv"); ccrsa_test_make_priv(); if(verbose) diag("Test ccrsa_recover_priv"); test_recover_priv_key(); if(verbose) diag("Test ccrsa_generate_prime\n"); test_generate_prime(); if(stdgen) { #if CORECRYPTO_HACK_FOR_WINDOWS_DEVELOPMENT diag("*skipping tests on Windows"); #else for (size_t r=0;r