I ran into some issues writing a small test programme using the cryptoki library. I want (have) to get hold of the RSA private key (all its parameters). I thought about either generate keys and then extract the parameters or use already generated parameters to set the keys manually. So far, I don't get any of this working. Code is at the end of the post.
Extraction
I know that there is the C_GetAttributeValue() with which I can extract attributes such as the public exponent or the modulus. That works for both public and private key objects but I get CKR_ATTRIBUTE_SENSITIVE error for when I try to extract private parameters from the private key object. Is there a way to extract these attributes? Can/Do I have to set certain parameters when logging into a session or during initialising?
Setting Keys manually
My second approach was to read key material (generated with OPENSSL) from a file and use that for generating key objects with C_CreateObject(). The file contains all RSA parameters (n,e,d,p,q,dmp1,dmq1,iqmp). After reading, I convert them from ASCII to hex representation and store them in a CK_BYTE[]. So far so good. Now, when I pass all this to the C_CreateObject() in order to create a private key I receive a CKR_ATTRIBUTE_VALUE_INVALID error message. Creating a public key object the same way with the public parameters works. I verified that using C_GetAttributeValue() on the created public key object.
What am I missing for generating a private key object if this is even possible this way?
I suppose that C_GenerateKeyPair() always generates new keys no matter whether key material is provided or not, right?
C Code
This is what I try to create the private key object with:
CK_OBJECT_HANDLE hPrivateKeys[NUMKEYS];
CK_KEY_TYPE kType= CKK_RSA;
CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY;
CK_BYTE id[] = {123};
CK_UTF8CHAR label[] = "An RSA private key object";
// sn,sd,se, etc contain the length of the respective parameter
CK_ATTRIBUTE privateKeyTemplate[] = {
{CKA_CLASS, &kClass, sizeof(kClass)},
{CKA_KEY_TYPE, &kType, sizeof(kType)},
{CKA_TOKEN, &false, sizeof(false)},
{CKA_PRIVATE, &false, sizeof(false)},
{CKA_SENSITIVE, &false, sizeof(false)},
{CKA_EXTRACTABLE, &true, sizeof(true)},
{CKA_ID, id, sizeof(id)},
{CKA_SUBJECT, NULL_PTR, 0},
{CKA_DECRYPT, &true, sizeof(true)},
{CKA_SIGN, &true, sizeof(true)},
{CKA_LABEL, label, sizeof(label)-1},
{CKA_ID, id, sizeof(id)},
{CKA_MODULUS, modulus, sn},
{CKA_PUBLIC_EXPONENT, publicExponent, se},
{CKA_PRIVATE_EXPONENT, privateExponent, sd},
{CKA_PRIME_1, prime1, sp},
{CKA_PRIME_2, prime2, sq},
{CKA_EXPONENT_1, exponent1, sdmp1},
{CKA_EXPONENT_2, exponent2, sdmq1},
{CKA_COEFFICIENT, coefficient, siqmp}
};
CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_ENCRYPT, &true, sizeof(true)},
{CKA_VERIFY, &true, sizeof(true)},
{CKA_WRAP, &true, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, se},
{CKA_MODULUS, modulus, sn}
};
rv = pFunctionList->C_CreateObject(hSession, privateKeyTemplate, NUM_ELEM(privateKeyTemplate), &hPrivateKeys[j]);
Your idea of generating a key pair and then reading it out is fine, you should however set the attribute CKA_SENSITIVE to false in the template of the private key. Note that it always depends on the token itself if such functionality is supported.
Usually when extracting private key information from a token you want to have it encrypted. Encryption of keys is called wrapping, and the possible extraction of sensitive information is managed by the CKA_EXTRACTABLE attribute.
After reading, I convert them from ASCII to hex representation and store them in a CK_BYTE[].
The PKCS#11 token interface specifies precisely how to encode / decode attributes. Just trying formats haphazardly is not going to give any results.
Related
I want to use a public/private key pair (ECDSA using secp256r1 curve) to sign commands sent to an embedded device via BLE, and verify them on the device. This means sending the public key to the embedded device (during registration) and storing the public key on the device. When a command is received by the device, the public key is used to verify the signature with mbedtls.
To keep things simple and efficient, I thought it would be best to send and store the uncompressed 64 byte data from the public key (i.e. x and y co-ordinates).
I can generate a key pair and extract the 64 bytes of the public key in my Android app, and send these to the device using BLE.
However, I haven't found a good way to use this public key data to verify signatures with embedtls - i.e. to load the raw 64 bytes into a suitable mbedtls_ecp_keypair struct.
I have been able to do it with "mbedtls_ecp_point_read_string" as follows (error checking removed for brevity):
// public_key_data is buffer containing 64 bytes (32 bytes X, 32 bytes Y).
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
mbedtls_ecp_keypair public_key;
mbedtls_ecp_keypair_init(&public_key);
mbedtls_ecp_point_init(&public_key.Q);
mbedtls_ecp_group_init(&public_key.grp);
mbedtls_ecp_group_load(&public_key.grp, MBEDTLS_ECP_DP_SECP256R1);
// Convert raw bytes of public key (public_key_data) to ASCII string (hex format).
// BytesToHexStr is C function to convert bytes to string:
char x_str[65]; // 2 x 32 bytes + 1 byte for terminating NUL
char y_str[65];
BytesToHexStr(public_key_data, x_str, ...);
BytesToHexStr(public_key_data + 32, y_str, ...);
// Get ECP point from string...
mbedtls_ecp_point_read_string(
&public_key.Q, // mbedtls_ecp_point *P,
16, // int radix,
x_str, // const char *x,
y_str // const char *y
);
mbedtls_ecdsa_from_keypair(&ecdsa, &public_key);
// Generate hash of message:
mbedtls_sha256_ret(message, message_size, hash, SHA_256);
// Verify signature:
int verify_result = mbedtls_ecdsa_read_signature(&ecdsa, hash, sizeof(hash), signature, signature_size);
// Check verify_result, clean up, etc.
However, this seems cumbersome.
I tried using the "mbedtls_ecp_point_read_binary" function with my raw public key, but it returned -20096 (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). The mbedtls documentation says "This function imports a point from unsigned binary data", but it doesn't give any details about what format the data is expected to be in.
Is there a better way to transfer / store / load ECDSA public key data with mbedtls?
I faced the exact same problem today.
Eventually figured out that mbedtls_ecp_point_read_binary expects binary data in uncompressed public key format, i.e 0x04 followed by X followed by Y.
If you've found this post for a similar but slightly different situation in that you are trying to use mbedtls_ecp_point_read_binary to read in your peer's public key (for ECDSA or ECDH key exchange for example), however your peer has only sent a compressed public key (33 bytes), there's a solution for this but it's limited to only a certain set of curves in mbedtls.
If you try mbedtls_ecp_point_read_binary to read in your peer's public key in compressed format you'll get a 0x4F80 (MBEDTLS_ERR_ECP_BAD_INPUT_DATA) error. The issue is exactly what #regnarts says (you need a decompressed key).
The challenge is that mbedtls doesn't support key decompression. Only tangentially related here but you can read into why that is here and here. Long story short, what emerged was a handy library (see link below) that correctly decompresses a key in binary format for a limited set of curves. Because it only supports those limited set of curves it wasn't incorporated into mbedtls, but it solved my problem so it's worth trying.
https://github.com/mwarning/mbedtls_ecp_compression
Some context: I have a PKCS #11-compliant cryptographic engine. This engine will be used to handle signed/enveloped data, i.e. verify the data's ECDSA/SHA1 signature, unwrap the symmetric key with RSAES-OAEP, and decrypt this data. This means the symmetric key will be wrapped with my engine's public key: hence I'd like the certificate for this public key to actually read "Subject Public Key Algorithm: RSAES-OAEP".
I'm looking for a C library which will let me manipulate objects comforming to the Cryptographic Message Syntax (CMS) and X.509 standards in the following way:
create a X.509 Certificate Signing Request (CSR), setting the Subject Public Key Algorithm to RSAES-OAEP
let me handle the signing part: my private key is only accessible via a PKCS #11 handle, so I need the library to give me the bytes to sign, and then let me set the CSR's ProofOfPossession field with what my crypto engine computed
export the complete CSR to something (DER or PEM)
create CMS structures to hold something like SignedData( EnvelopedData( stuff )). The library could handle the actual encryption/key wrapping/signature, or it could let some other software engine do it and just allow me to set the octet strings
let me easily parse back the message and recover those octet strings
meaning I want to open a DER/PEM file which contains this CMS message, and get the bytes for the signature, the wrapped key and the encrypted stuff, so that I can feed them to my PKCS #11 interface
Before anyone suggests OpenSSL's libcrypto, I've looked at it (looked as in, "spent the last week trying to understand how the structures work, how the ASN.1 representation works, how I can recover the bytes I'm interested in from OpenSSL's structures..."), and I have some issues with it (as of 1.0.1f):
(cf 1.) I cannot set the Subject Public Key Algorithm to RSAE-OAEP. Starting from demos/x509/mkreq.c, and going all the way back to the deep reaches of x509t.h's weird #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) macros, I think I can affirm that X509_REQ_set_pubkey() cannot handle OAEP.
(cf 2.) Neither can the CMS part of the crypto lib, for that matter. cms_RecipientInfo_ktri_encrypt() calls EVP_PKEY_CTX_ctrl(), which I guess resolves to crypto/rsa/rsa_pmeth.c:pkey_rsa_ctrl(): when p2 is EVP_PKEY_CTRL_CMS_ENCRYPT, p2 is not parsed, so RSA padding is not set (if it turns out I'm wrong and I just cannot read code correctly, please tell me).
So while I'm glad this guy managed to make it "work like a charm", I cannot share his enthusiasm.
I guess for 2. I could use OpenSSL to create CMS blank structures, compute the future EnvelopedData content (ie stuff encrypted with a symmetric key + symmetric key wrapped with RSA OAEP), and stuff this content into the structures, bypassing CMS_encrypt() completely, before encapsulating into a SignedData (I'm assuming CMS_sign() will handle ECDSA/SHA1). As long as I don't want to use fancy parameters for OAEP (although this other guy managed to patch the lib to use OAEP with SHA-256).
But this might end up requiring a tad too much fiddling with OpenSSL's ASN.1 API. Hence my interrogation: does anyone know of a C library to build CMS structures and feed them the octet strings computed by some other engines? Also how to build certificates which read "THIS KEY IS MEANT TO BE USED WITH RSAES-OAEP".
I've looked at libksba and cryptlib and while I guess they could work, I cannot see how to use them yet (might have something to do with my eyes bleeding from staring at OpenSSL's code so much - I do not mean to say that OpenSSL's code is bad or anything, just that I've been looking at it hard, and the doc is slightly lacking).
Actually, I guess, I could drop the C requirement (mainly there because communicating with the crypto engine is done in PKCS #11/C). Here's what the library should be able to do:
build a CSR
... featuring "RSAES-OAEP" as Subject Public Key Algorithm
give me the bytes to sign for the Proof-of-Possession part
take the signature and output a complete X.509 CSR
parse a CMS structure
(SignedData) give me the bytes corresponding to the signedInfo->signature and encapsulatedContentInfo fields so that I can verify them with some other engine
(EnvelopedData) give me the bytes corresponding to the keyTransRecipientInfo->encryptedKey and encryptedContentInfo->encryptedContent fields so that I can unwrap/decrypt with some other engine
build a CMS structure, either...
letting some external engine set the fields mentioned above, and letting me specify the algorithms
actually implementing the algorithms, and building the CMS from just the data (... with RSAES-OAEP for key wrapping)
Right now I'm going with a "all-OpenSSL" approach, because I feel like I'm in too deep and should not start wandering somewhere else. If anybody has a better idea, I am all ears.
As for setting that subject public key algorithm... Well, either I'll just leave regular RSA and have my application "know" that wrapping is RSAES-OAEP, or... I don't know. And as for signing the request... is POP all that useful anyway?
(This is not a serious question)
NB: edited to remove the whole "I want my certificate to read OAEP", since I just found out about RFC 5756 (also found an interesting discussion from 2006 when this RFC was not out yet).
Here's what I managed to get working so far.
1. Building a CSR, signing it with some other engine
I mostly followed demos/x509/mqreq.c, with some twists.
(NB: error checking, fancy modulus length/label/subject DN generation/handling has been left out for brevity and focus on actual flow).
unsigned char* mod = NULL;
unsigned char* exp = NULL;
size_t mod_l = 0;
size_t exp_l = 0;
P11_handle h_key = P11_gen_rsa(&mod, &mod_l, &exp, &exp_l);
RSA* rsa = RSA_new();
rsa->n = BN_bin2bn(rsa_mod, rsa_mod_l, NULL);
rsa->e = BN_bin2bn(rsa_exp, rsa_exp_l, NULL);
EVP_PKEY* pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);
X509_REQ* csr = X509_REQ_new();
X509_REQ_set_pubkey(csr, pkey);
/* Boring X509_NAME/X509_EXTENSION stuff */
X509_REQ_INFO* csr_req = csr->req_info;
unsigned char* pop_in = NULL;
size_t pop_in_l = ASN1_item_i2d((void*)csr_req, &pop_in,
ASN1_ITEM_rptr(X509_REQ_INFO));
unsigned char* sig = NULL;
size_t sig_l = 0;
P11_make_pop(SIGN_RSA_PKCS, DIGEST_SHA256,
pop_in, pop_in_l, &sig, &sig_l,
h_key);
/* Add signature to CSR (heavily inspired from ASN1_item_sign_ctx())
* (please don't ask about the flags) */
if (csr->signature->data != NULL) OPENSSL_free(csr->signature->data);
csr->signature->data = sig;
csr->signature->length = sig_l;
csr->signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
csr->signature->flags|= ASN1_STRING_FLAG_BITS_LEFT;
/* Add signature algorithm information to CSR */
int sig_algo_nid = 0;
OBJ_find_sigid_by_algs(&sig_algo_nid,
EVP_MD_nid(EVP_sha256()), EVP_PKEY_RSA);
X509_ALGOR_set0(csr->sig_alg, OBJ_nid2obj(sig_algo_nid),
V_ASN1_NULL, NULL));
After that, the X509_REQ structure is good for PEM export. openssl req -verify seems to validate the process, so as far as I'm concerned this works.
2. Building nested CMS structures (as in SignedData(EnvelopedData(Data)))
Finally got it, using 1.0.2 (any previous version would have needed patching or ASN.1-level parsing). Many thanks to Dr. Stephen Henson and Tom Francis for helping me with this via the mailing list.
/* Make EnvelopedData structure */
BIO* in = BIO_new_file(in_path, "rb");
int flags = CMS_BINARY | CMS_USE_KEYID | CMS_PARTIAL | CMS_KEY_PARAM;
CMS_ContentInfo* edata = CMS_encrypt(NULL, NULL, cipher, flags);
CMS_RecipientInfo* r_info = CMS_add1_recipient_cert(edata, r_cert, flags);
EVP_PKEY_CTX* wrap_ctx = CMS_RecipientInfo_get0_pkey_ctx(r_info);
EVP_PKEY_CTX_set_rsa_padding(wrap_ctx, RSA_PKCS1_OAEP_PADDING);
EVP_PKEY_CTX_set_rsa_oaep_md(wrap_ctx, EVP_sha256());
EVP_PKEY_CTX_set_rsa_mgf1_md(wrap_ctx, EVP_sha256());
EVP_PKEY_CTX_set0_rsa_oaep_label(wrap_ctx, oaep_label, oaep_label_l);
/* NB: oaep_label must be heap-allocated, and will be freed by OSSL */
CMS_final(edata, in, NULL, flags);
BIO* tmp = BIO_new(BIO_s_mem());
i2d_CMS_bio(tmp, edata);
/* Make SignedData structure */
flags|= CMS_NOSMIMECAP | CMS_NOCERTS;
flags&= ~(CMS_KEY_PARAM);
CMS_ContentInfo* sdata = CMS_sign(NULL, NULL, NULL, NULL, flags);
ASN1_OBJECT* ectype_edata = OBJ_nid2obj(NID_pkcs7_enveloped);
CMS_set1_eContentType(sdata, ectype_edata);
CMS_SignerInfo* s_info =
CMS_add1_signer(sdata, s_cert, s_key, NULL, flags);
CMS_SignerInfo_sign(s_info);
CMS_final(sdata, tmp, NULL, flags);
BIO* out = BIO_new_file(out_path, "wb");
i2d_CMS_bio(out, sdata);
BIO_flush(out);
3. Parsing the structure and getting the fields I need.
I basically wrote my own CMS parser. ASN.1 is actually simple to parse when you know the spec. I've tried compiling the ASN.1 modules in the RFC using some "ASN.1 to C structs" compilers but had no luck (they kept choking on the syntax).
I need to calculate the md5 of a file saved locally in an windows8 app created in
javascript / html.
I need the md5 to compare it with an online file and see if the two objects are really the same.
What function should I use?
Here's the code I use to hash a string in MD5 using Windows.Security.Cryptography namespace:
var inputBuffer, outputBuffer, toHash, hashed,
hashProvider = Windows.Security.Cryptography.Core.HashAlgorithmProvider.openAlgorithm(Windows.Security.Cryptography.Core.HashAlgorithmNames.md5); // "open" an md5 hash provider
toHash = 'string'; // string to hash
inputBuffer = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(toHash, Windows.Security.Cryptography.BinaryStringEncoding.utf8); // convert string to binary
outputBuffer = hashProvider.hashData(inputBuffer); // hash the binary
hashed = Windows.Security.Cryptography.CryptographicBuffer.encodeToHexString(outputBuffer); // the hashed string
Now, all you need to do is to read the file in (see http://msdn.microsoft.com/en-us/library/windows/apps/hh464978.aspx). If reading the file into a buffer, then you wouldn't need the convertStringToBinary line.
The WinRT API provides SHA functionality in the Windows.Security.Cryptography.Core namespace, specifically through the static method HashAlgorithmProvider.openAlgorithm(Windows.Security.Cryptography.Certificates.HashAlgorithmNames.sha256).
This provides you with a HashAlgorithmProvider class that has methods like hashData.
Fin in this Link is all that's available in winjs in terms of cryptography.
And Here you can find an example on how to implement an MD5 calculator for a string, from there is a good start to make it work for a file.
Hope this helps.
I'm trying to find out the unboundid AttributeSyntax type for a specific attribute name and it's simply not working.
Here's the example test code that I'm using to achieve this:
#Test
public void testLDAPSchema() {
try {
LDAPConnection connection = new LDAPConnection();
connection.connect("hessmain", 389);
connection.bind("CN=Administrator,CN=Users,DC=FISHBOWL,DC=NET", "password");
Schema s = connection.getSchema();
System.out.println(s.toString());
AttributeTypeDefinition atd = s.getAttributeType("directReports");
Set<AttributeTypeDefinition> oat = s.getOperationalAttributeTypes();
Set<AttributeSyntaxDefinition> l = s.getAttributeSyntaxes();
AttributeSyntaxDefinition asd1 = s.getAttributeSyntax(atd.getOID());
AttributeSyntaxDefinition asd2 = s.getAttributeSyntax(atd.getSyntaxOID());
AttributeSyntaxDefinition asd3 = s.getAttributeSyntax(atd.getBaseSyntaxOID());
connection.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
From the above code, all the sets are empty. This also means that no matter which OID I pass to the schema getAttributeSyntax method that I will simply get a null return.
Is there any reason why I can't get the attribute syntaxes from an Active Directory server schema?
Thanks
I don't think that this is specific to the UnboundID LDAP SDK for Java. I'm not sure that Active Directory exposes this information over LDAP. When I perform a general LDAP search to retrieve schema information, I can see the attributeTypes and objectClasses attributes, but ldapSyntaxes isn't returned (and in fact ldapSyntaxes doesn't appear in the list of attribute types).
Similarly, none of the attribute type definitions includes a USAGE element, which is what is used to indicate that the attribute type is operational (e.g., "USAGE directoryOperation").
It may well be that Active Directory simply doesn't report this information at all. It could be that it provides some other non-standard way to get this information (e.g., a control or extended operation, or some other entry that can be retrieved), but if there is then I don't know about it.
I want to feed OpenSSL specific data for use as random seed during the signing of data with an EC key. I'm doing this to compare my application with another reference one (closed source). That utility takes the file with private key, file with data to sign and file with random data as parameters.
I've got the generation of EC keys, and signing of data down, but can't compare the two applications since I have no common ground. OpenSSL generates random data used in signing the data (probably from /dev/random) and thus gives me a different signature every run.
I've tried RAND_clear() in combination with RAND_add(), but keep getting changing signatures. Either I don't understand the whole ECDSA concept, or I'm doing something wrong.
My second option for comparing the applications is to import the public key and verify the signature generated by the reference program. This is the better option, but I'm unable to import the given example public key (83 character hex string). EC_POINT_oct2point() keeps giving me null results.
Any help/pointers/references would be greatly appreciated.
char * key_as_binary_data; //369368AF243193D001E39CE76BB1D5DA08A9BC0A63307AB352338E5EA5C0E05A0C2531866F3E3C2702
int data_size; //Size of the key buffer
EC_POINT * ecpoint = NULL;
EC_GROUP * ecgroup = NULL;
EC_KEY * eckey = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
int asn1_flag = OPENSSL_EC_NAMED_CURVE;
eckey = EC_KEY_new();
ecpoint = EC_POINT_new(ecgroup);
ecgroup = EC_GROUP_new_by_curve_name(OBJ_sn2nid("sect163k1"));
EC_GROUP_set_asn1_flag(ecgroup, asn1_flag);
EC_GROUP_set_point_conversion_form(ecgroup, form);
EC_KEY_set_group(eckey,ecgroup);
EC_KEY_generate_key(eckey);
//This gives me a null ecpoint
EC_POINT_oct2point(ecgroup,ecpoint,key_as_binary_data,data_size-1,ctx);
EC_KEY_set_public_key(eckey,ecpoint);
This is how you should go about loading that public key:
EC_KEY *key = NULL;
EC_POINT *pub_key;
const EC_GROUP *group;
SSL_library_init();
SSL_load_error_strings();
key = EC_KEY_new_by_curve_name(NID_sect163k1);
group = EC_KEY_get0_group(key);
pub_key = EC_POINT_new(group);
EC_POINT_hex2point(group,
"369368AF243193D001E39CE76BB1D5DA08A9BC0A63307AB352338E5EA5C0E05A0C2531866F3E3C2702", pub_key, NULL);
EC_KEY_set_public_key(key, pub_key);
if (!EC_KEY_check_key(key)) {
printf("EC_KEY_check_key failed:\n");
printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
} else {
printf("Public key verified OK\n");
}
It seems to verify OK, so it should work for checking a signature.
I think your bug might have just been passing a NULL (in ecgroup) to EC_POINT_new().
The reason you get different results despite the fact that you are clearing the pool and resetting it is that by default OpenSSL's RAND implementation will hash the pid into the output block (precisely to ensure that even applications that use the same seed do not get the same PRNG output, since 99.9% of the time that happening is a Bad Thing).
In addition, even if this was not the case, it is unlikely that your reference application uses the same PRNG that OpenSSL uses to turn the seed file into a series of random bytes. (Unless your reference application actually uses OpenSSL as well, of course). What you would have to do is first figure out what kind of PRNG the reference app uses - this might be a standard PRNG design like the ones from X9.31 or FIPS-186, or might be something totally custom. Then reimplement that design for OpenSSL and plug it in via RAND_set_rand_method.
As to verification: it looks like you need to transpose the lines:
ecpoint = EC_POINT_new(ecgroup);
ecgroup = EC_GROUP_new_by_curve_name(OBJ_sn2nid("sect163k1"));
Otherwise ecpoint is set to NULL right from the start, and this causes EC_KEY_generate_key to fail, because the group is set to NULL. Quoting from openssl-0.9.8k's crypto/ec/ec_key.c:
if (!eckey || !eckey->group)
{
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
You can control the random data that OpenSSL produces during signing by using the method:
ECDSA_SIG* ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
where kinv is the random number that is used during signing.
The signing procedure is purely to allow someone else to confirm that you signed it ie. it was your private key that was used to sign the message (or any data) without actually having your private key.
The algorithm is outlined on wikipedia Elliptic_Curve_DSA
Reading "Signature generation algorithm" it appears the random data is used to assist in the strength of the signature and to make it harder to attack to figure out the private key.
Therefore you should expect the signature to be different each time since this is not just simply a hash.
See the section "Signature verification algorithm" to see that the verification steps are the ones you wish to use to confirm that your openssl version is outputing valid signatures w.r.t. the ECDSA method and the closed source program.
I can't find the docs for RAND_clear, so can't comment why it's not resulting in reproducible random numbers.
But even if you get that done, what you want may not be possible. ECDSA signature generation requires choosing a random integer in a particular range. Two different implementations of the algorithm might have completely different ideas about how to generate such an integer from their entropy source. AFAIK the means of transforming bits of entropy into the required number is not part of the ECDSA algorithm.
So for example (very bad examples of course), one implementation might do this:
int random_number = rand() % n;
and another might do this:
int random_number = (rand() * n) / RAND_MAX;
So even if you give them the same seed data, you might still get different signatures from different implementations. All you can do is validate whether you have generated a valid signature.