I am looking for examples of calling the libtomcrypt ecc sign and verify code using inputs created using the OpenSSL command line. I have created private and public keys, using the prime256v1 curve, created a signature for a text file and verified it using the command line. I have pulled those keys and the signature in to my C++ test driver and used the libtomcrypt methods to import those. I created the hash of the text file using the openssl command line and put that into my test driver as well, but when I call the libtomcrypt ecc_verify_hash method, it fails to verify. At this point I have verified that the keys and the signature are importing correctly, so I'm not sure what I'm doing incorrectly.
Here is the code for my test driver. Any help with this would be greatly appreciated.
int main ()
{
ltc_mp = ltm_desc;
int idx = 0;
prng_state myPrng;
//unsigned char buf[4096];
//unsigned long b;
int stat, err;
ecc_key pubKey;
ecc_key privKey;
void* sig;
static unsigned char MSG_STR[] = "Test Message";
const int MSG_STR_LEN = 12;
static unsigned char DGST[] =
"C87D25A09584C040F3BFC53B5701199591DEB10BA";
const int DGST_LEN = 41;
// the DER forms of the keys
static unsigned char PRIV_KEY[] =
{
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x4f,
0xab, 0xef, 0xfb, 0x6a, 0xe4, 0xcd, 0xd5, 0x83,
0xb7, 0x39, 0x57, 0xf5, 0x63, 0xd4, 0x60, 0xa6,
0x83, 0x26, 0x56, 0xb8, 0x1e, 0x78, 0xee, 0x3d,
0xf0, 0xa9, 0xe8, 0x3b, 0x2c, 0x34, 0xc1, 0xa0,
0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00,
0x04, 0x24, 0x72, 0xcb, 0x56, 0xb5, 0xae, 0x0a,
0x8e, 0x14, 0xc9, 0x89, 0x3d, 0xc8, 0x61, 0xb6,
0xed, 0x74, 0xa2, 0x2f, 0x15, 0xb7, 0x31, 0x14,
0xc6, 0xd5, 0x38, 0x71, 0xaa, 0x3f, 0x52, 0x5c,
0x8e, 0x3e, 0x59, 0xaa, 0x68, 0xcd, 0xcd, 0x8c,
0x2c, 0x63, 0x9b, 0xbc, 0x46, 0x79, 0x87, 0xd4,
0xdd, 0x4f, 0xbd, 0x97, 0x2b, 0xc2, 0x6a, 0x5d,
0x5c, 0xb5, 0xc7, 0x91, 0xaa, 0x15, 0xf8, 0x7c,
0x27
};
const int PRIV_KEY_LEN = 121;
static unsigned char PUB_KEY[] =
{
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00, 0x04, 0x24, 0x72, 0xcb, 0x56, 0xb5,
0xae, 0x0a, 0x8e, 0x14, 0xc9, 0x89, 0x3d, 0xc8,
0x61, 0xb6, 0xed, 0x74, 0xa2, 0x2f, 0x15, 0xb7,
0x31, 0x14, 0xc6, 0xd5, 0x38, 0x71, 0xaa, 0x3f,
0x52, 0x5c, 0x8e, 0x3e, 0x59, 0xaa, 0x68, 0xcd,
0xcd, 0x8c, 0x2c, 0x63, 0x9b, 0xbc, 0x46, 0x79,
0x87, 0xd4, 0xdd, 0x4f, 0xbd, 0x97, 0x2b, 0xc2,
0x6a, 0x5d, 0x5c, 0xb5, 0xc7, 0x91, 0xaa, 0x15,
0xf8, 0x7c, 0x27
};
const int PUB_KEY_LEN = 91;
static unsigned char OPENSSL_SIG[] =
{
0x30, 0x46, 0x02, 0x21, 0x00, 0xf3, 0x69, 0xd9,
0xaf, 0xad, 0xc7, 0x16, 0xac, 0x03, 0x9a, 0x5c,
0xae, 0xf7, 0x05, 0x86, 0x56, 0x24, 0x18, 0x09,
0x44, 0x3b, 0x07, 0xc9, 0xec, 0x6b, 0x72, 0x69,
0x18, 0x13, 0x10, 0xd7, 0x32, 0x02, 0x21, 0x00,
0xd5, 0xa1, 0x21, 0xc0, 0xf8, 0x5d, 0xb6, 0x6f,
0x46, 0x04, 0x9b, 0x2e, 0x1f, 0x96, 0xdc, 0x55,
0xd6, 0x5e, 0xc5, 0x14, 0x3c, 0x68, 0x70, 0x2a,
0x0c, 0x17, 0xad, 0xa1, 0xb8, 0x90, 0x0b, 0x07
};
const int OPENSSL_SIG_LEN = 72;
static unsigned char RAND_DATA[] =
"8e2582c586c37099c3126170e48352c5416c41ef44972ec0708ef2caab08"
"583f10b277276c2507dee509a0c492bb806108590db675f6d908025999a6"
"7cc049290fe4ea0beb6b62004cbc82c580e5c00fa360d2f55b565535f6ec"
"41a2adfe83ffc3a2007ee1e1ba03b94fb777350e1c3a2caffcf6434534bd"
"8d29c2b62a9abf279c9a419a53ae54c3f22d0d0886ced81d7422bfb2493b"
"2231d8aad890d80f1dc42280e6803fa768d2a5ebaf954e91713d9e0d93d9"
"9749b7b29d8deac683fa930d39758212020e6ebc850993804ce6a6a969a3"
"261ad870040634bb2c506c911e06b20ab723d03df239c39ecf210fa67ab2"
"54573c5531a475c3e7158eb89074a77238182b9b72d0f4d1407cffb6d59c"
"53ec202a5b36bd649b2a6f31ad182072d549402df2e1ed8289ad08973444"
"1269bbccca6bc8899e8a750329c35a1c7a19281bf90c1575ebc5c197e19f"
"5cc4e3f3dd5f507df6457a6e39b4609a774c11e5b15210d2a49ee3dab9e3"
"fb89966b8fa83cc9c3045f67001f8447d9d035c512f3c1c6332c701b403c"
"52d424d116b78426e013e34b1c3b7dbf87669970799a719971e1583135db"
"727ea7297bf76d093fc4648fca0cf79dbd6144963061838178d8b32efe9d"
"ee5ff58e9c6e6fc922b9e94631c7d76e06a0d28fc1c40d634e65e332ed4d"
"ff85293e5a9f103410c5e974775be91a773508293b5fcd8672a1a30640a7"
"9e42755d2b5229292848b6e56b540ba2d1bd2e7e5d61895293c5e9ee83ce"
"bba4194a3191fc9f0e6924835761c512d0515bb63b334c5e98dc0d43e7ce"
"3ee11e46872e4d8d767104189429f5cbcf4fd8db7c3022dd5e5ae99f5a48"
"e595fdff8d9db23e3beebef219341c53aa7e6da2fad750d2a648b58a0151"
"d0b029cf5d1900b65c047b95dd3004a048be4611d49f6a96f3f054b3c476"
"4b2e1a521a57e46b3df537d8a442726ce0e318fc356538e888d8825edfa2"
"4c3c42716a628c331db6261455c9c5d4b98d466f4831d28a6f9eb2abe758"
"38f81ca42e06f362d3d263a9c0e7bffaff635fc640434b02dd2f740a4737"
"6180bbe217436b86d481f83825e28b92ab3444b7c3326e18d796ac9c2633"
"4d9cc9310f29f42dfe4d9b53bd40b7f1433708c87ad412bbf8b646ec1468"
"76a8083e08029de1b84f7ebb606bf84a59dc7f1b46df2cc5c0ba5008761d"
"9da2344434f524e7ad6e648964a761907c1a0ccb1fdee645ad7aaf4ea0c8"
"68fd39ae75b2bc41b8c86f5adaa2105f84e9b187c5a887c9e0d726383564"
"34fe79c7ae0460cc7eddffe3f3109f83cf7a80ba8432ff9dd9f0b664cb6d"
"fc215800e4253d0bfa1a74df5f7b52f0d0ac9e3ce1af856058d7c2b117ae"
"7a5a7cfac7ea592e88c8417d16fe10f4545af981e937fb194c26a2e44f3f"
"40ea26dd794ad8f2d16f36eb27c6eaa6780925e8d7e96dfdde483800a9b3"
"95c7a358";
const int RAND_DATA_LEN = 2049;
ltm_desc.init(&privKey.k);
ltm_desc.init(&pubKey.pubkey.x);
ltm_desc.init(&pubKey.pubkey.y);
ltm_desc.init(&pubKey.pubkey.z);
ltm_desc.init(&sig);
// set up the random number generator
if ((err = register_prng(&yarrow_desc)) != CRYPT_OK) {
cout << "Failed to register prng. Err = " << err << endl;
return err;
}
if ((err = yarrow_start(&myPrng)) != CRYPT_OK) {
cout << "Yarrow failed to start! Err = " << err << endl;
return err;
}
if ((err = yarrow_add_entropy(RAND_DATA, RAND_DATA_LEN, &myPrng))
!= CRYPT_OK) {
cout << "Failed adding entropy Err = " << err << endl;
return err;
}
if ((err = yarrow_ready(&myPrng)) != CRYPT_OK) {
cout << "Failed to set state to ready. Err = " << err << endl;
return err;
}
// read in the private key information
if ((err = ecc_import_openssl(PRIV_KEY, PRIV_KEY_LEN, &privKey))
!= CRYPT_OK)
{
cout << "Failed to import private key, err =" << err << endl;
return err;
}
// read in the public key information
if ((err = ecc_import_openssl(PUB_KEY, PUB_KEY_LEN, &pubKey))
!= CRYPT_OK)
{
cout << "Failed to import public key, err =" << err << endl;
return err;
}
// try to verify the signature created using OpenSSL
// with the libtom verify method
if (((err = ecc_verify_hash(OPENSSL_SIG,
OPENSSL_SIG_LEN,
DGST,
DGST_LEN,
&stat,
&pubKey)) != CRYPT_OK)) {
cout << "Failed to verify OpenSSL signature using libtom. Error ="
<< err << endl;
return err;
} else if (stat == 0) {
cout << "Failed to verify OpenSSL signature using libtom. Error ="
<< err << endl;
return err;
}
else {
cout << "Successfully verifed OpenSSL signature using libtom."
<< endl;
}
ecc_free (&pubKey);
ecc_free (&privKey);
}