int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* * create and verify a ecdsa signature with every availble curve (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) /* drop the curve */ { EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong length */ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* * Modify a single byte of the signature: to ensure we don't garble * the ASN1 structure, we read the raw signature and modify a byte in * one of the bignums directly. */ sig_ptr = signature; if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(ecdsa_sig->r); s_len = BN_num_bytes(ecdsa_sig->s); bn_len = (degree + 7) / 8; if ((r_len > bn_len) || (s_len > bn_len)) { BIO_printf(out, " failed\n"); goto builtin_err; } buf_len = 2 * bn_len; if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) goto builtin_err; /* Pad the bignums with leading zeroes. */ memset(raw_buf, 0, buf_len); BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } /* * Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ /* clean bogus errors */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: if (eckey) EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (signature) OPENSSL_free(signature); if (raw_buf) OPENSSL_free(raw_buf); if (curves) OPENSSL_free(curves); return ret; }
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig) { unsigned int nSize = ECDSA_size(pkey); vchSig.resize(nSize); // Make sure it is big enough if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey)) { vchSig.clear(); return false; } vchSig.resize(nSize); // Shrink to fit actual size return true; }
data_chunk elliptic_curve_key::sign(hash_digest hash) const { BITCOIN_ASSERT(key_ != nullptr); // SSL likes a reversed hash std::reverse(hash.begin(), hash.end()); data_chunk signature(ECDSA_size(key_)); unsigned int signature_length = signature.size(); if (!ECDSA_sign(0, hash.data(), hash.size(), signature.data(), &signature_length, key_)) return data_chunk(); signature.resize(signature_length); return signature; }
extern "C" int32_t CryptoNative_EcDsaSign(const uint8_t* dgst, int32_t dgstlen, uint8_t* sig, int32_t* siglen, EC_KEY* key) { if (!siglen) { return 0; } unsigned int unsignedSigLength = UnsignedCast(*siglen); int ret = ECDSA_sign(0, dgst, dgstlen, sig, &unsignedSigLength, key); *siglen = SignedCast(unsignedSigLength); return ret; }
int main(int argc, const char **argv) { BIO *in; EC_KEY *eckey; char challenge[BUFSIZE]; const unsigned char *workbuf_p; unsigned char *sig_buf, *sig_buf_p; size_t len; unsigned int buf_len, i; if (argv[1] == NULL || argv[2] == NULL) { fprintf(stderr, "usage: %s [keyfile] [base64challenge]\n", argv[0]); return EXIT_FAILURE; } in = BIO_new(BIO_s_file()); BIO_read_filename(in, argv[1]); eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (!EC_KEY_check_key(eckey)) { fprintf(stderr, "Key data for %s is inconsistent.\n", argv[1]); return EXIT_FAILURE; } memset(challenge, '\0', sizeof challenge); len = base64_decode(argv[2], challenge, BUFSIZE); workbuf_p = (unsigned char *) challenge; buf_len = ECDSA_size(eckey); sig_buf = mowgli_alloc(buf_len); sig_buf_p = sig_buf; if (!ECDSA_sign(0, challenge, len, sig_buf_p, &buf_len, eckey)) { fprintf(stderr, "Failed to sign challenge!\n"); return EXIT_FAILURE; } base64_encode(sig_buf, buf_len, challenge, BUFSIZE); printf("%s\n", challenge); mowgli_free(sig_buf); return EXIT_SUCCESS; }
bool bp_sign(struct bp_key *key, const void *data, size_t data_len, void **sig_, size_t *sig_len_) { size_t sig_sz = ECDSA_size(key->k); void *sig = calloc(1, sig_sz); unsigned int sig_sz_out = sig_sz; int src = ECDSA_sign(0, data, data_len, sig, &sig_sz_out, key->k); if (src != 1) { free(sig); return false; } *sig_ = sig; *sig_len_ = sig_sz_out; return true; }
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { unsigned int sltmp; EC_KEY *ec = ctx->pkey->pkey.ec; if (!sig) { *siglen = ECDSA_size(ec); return 1; } else if (*siglen < (size_t)ECDSA_size(ec)) { OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); return 0; } if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { return 0; } *siglen = (size_t)sltmp; return 1; }
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig) { if ( fUseOld044Rules ) { unsigned int nSize = ECDSA_size(pkey); vchSig.resize(nSize); // Make sure it is big enough if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey)) { vchSig.clear(); return false; } vchSig.resize(nSize); // Shrink to fit actual size return true; } vchSig.clear(); ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); if (sig==NULL) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); CBigNum order, halforder; EC_GROUP_get_order(group, &order, NULL); BN_rshift1(&halforder, &order); // enforce low S values, by negating the value (modulo the order) if above order/2. if (BN_cmp(sig->s, &halforder) > 0) { BN_sub(sig->s, &order, sig->s); } unsigned int nSize = ECDSA_size(pkey); vchSig.resize(nSize); // Make sure it is big enough unsigned char *pos = &vchSig[0]; nSize = i2d_ECDSA_SIG(sig, &pos); ECDSA_SIG_free(sig); vchSig.resize(nSize); // Shrink to fit actual size // Testing our new signature if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) { vchSig.clear(); return false; } return true; }
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *dgst, size_t dgstlen) { int ret; EC_PKEY_CTX *dctx = ctx->data; EC_KEY *ec_key = ctx->pkey->pkey.ec; int type; unsigned int len; if (!sig) { *siglen = ECDSA_size(ec_key); return 1; } else if (*siglen < (size_t)ECDSA_size(ec_key)) { ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); return 0; } if (dctx->sign_type != NID_secg_scheme && dctx->sign_type != NID_sm_scheme) { return 0; } if (dctx->md) type = EVP_MD_type(dctx->md); else if (dctx->sign_type == NID_secg_scheme) type = NID_sha1; else if (dctx->sign_type == NID_sm_scheme) type = NID_sm3; if (dctx->sign_type == NID_secg_scheme) { ret = ECDSA_sign(type, dgst, dgstlen, sig, &len, ec_key); } else if (dctx->sign_type == NID_sm_scheme) { ret = SM2_sign(type, dgst, dgstlen, sig, &len, ec_key); } if (ret <= 0) return ret; *siglen = len; return 1; }
STDMETHODIMP CBECC::DSASign(VARIANT varData, VARIANT *pVal) { if(m_pECC == NULL)return E_NOTIMPL; if (!EC_KEY_check_key((EC_KEY*)m_pECC)) return E_NOTIMPL; CBVarPtr varPtr; HRESULT hr = varPtr.Attach(varData); if(FAILED(hr))return hr; int nSize = ECDSA_size((EC_KEY*)m_pECC); CBVarPtr varVal; varVal.Create(nSize); if (!ECDSA_sign(0, varPtr.m_pData, varPtr.m_nSize, varVal.m_pData, (unsigned int *)&nSize, (EC_KEY*)m_pECC)) return E_INVALIDARG; return varVal.GetVariant(pVal, nSize); }
static int s2n_ecdsa_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature) { const s2n_ecdsa_private_key *key = &priv->key.ecdsa_key; notnull_check(key->ec_key); uint8_t digest_length; GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); lte_check(digest_length, S2N_MAX_DIGEST_LEN); uint8_t digest_out[S2N_MAX_DIGEST_LEN]; GUARD(s2n_hash_digest(digest, digest_out, digest_length)); unsigned int signature_size = signature->size; GUARD_OSSL(ECDSA_sign(0, digest_out, digest_length, signature->data, &signature_size, key->ec_key), S2N_ERR_SIGN); S2N_ERROR_IF(signature_size > signature->size, S2N_ERR_SIZE_MISMATCH); signature->size = signature_size; GUARD(s2n_hash_reset(digest)); return 0; }
// for now a copy of how we sign in libraries/networking/src/DataServerAccountInfo - // we sha256 the text, read the private key from disk (for now!), and return the signed // sha256. Note later with multiple keys, we may need the key parameter (or something // similar) so I left it alone for now. Also this will probably change when we move // away from RSA keys anyways. Note that since this returns a QString, we better avoid // the horror of code pages and so on (changing the bytes) by just returning a base64 // encoded string representing the signature (suitable for http, etc...) QString Wallet::signWithKey(const QByteArray& text, const QString& key) { EC_KEY* ecPrivateKey = NULL; if ((ecPrivateKey = readPrivateKey(keyFilePath()))) { const auto sig = std::make_unique<unsigned char[]>(ECDSA_size(ecPrivateKey)); unsigned int signatureBytes = 0; qCInfo(commerce) << "Hashing and signing plaintext" << text << "with key at address" << ecPrivateKey; QByteArray hashedPlaintext = QCryptographicHash::hash(text, QCryptographicHash::Sha256); int retrn = ECDSA_sign(0, reinterpret_cast<const unsigned char*>(hashedPlaintext.constData()), hashedPlaintext.size(), sig.get(), &signatureBytes, ecPrivateKey); EC_KEY_free(ecPrivateKey); QByteArray signature(reinterpret_cast<const char*>(sig.get()), signatureBytes); if (retrn != -1) { return signature.toBase64(); } } return QString(); }
int VNEcdsa_ORG_Sign( const VNAsymCryptCtx_t * ctx, const unsigned char * plainText, int length, struct vn_iovec * signText ) { int ret = 0; VNEcdsa_ORG_Ctx_t * orgCtx = VN_CONTAINER_OF( ctx, VNEcdsa_ORG_Ctx_t, mCtx ); assert( VN_TYPE_VNEcdsaSign_ORG == ctx->mType ); signText->i.iov_len = ECDSA_size( orgCtx->mEcKey ); signText->i.iov_base = malloc( signText->i.iov_len ); ret = ECDSA_sign( 0, plainText, length, signText->i.iov_base, (unsigned int *)&( signText->i.iov_len ), orgCtx->mEcKey ); if( 1 != ret ) { char buff[ 1024 ] = { 0 }; printf( "ECDSA_sign %d, %s\n", ret, ERR_error_string( ERR_get_error(), buff ) ); } return 1 == ret ? 0 : -1; }
/* * Sign a challenge. */ bool libecdsaauth_sign(libecdsaauth_key_t *key, unsigned char *in, size_t inlen, unsigned char **out, size_t *outlen) { unsigned char *sig_buf, *sig_buf_p; unsigned int sig_len; if (key->eckey == NULL) return false; sig_len = ECDSA_size(key->eckey); sig_buf = malloc(sig_len); sig_buf_p = sig_buf; if (!ECDSA_sign(0, in, inlen, sig_buf_p, &sig_len, key->eckey)) { free(sig_buf); return false; } *out = sig_buf; *outlen = (size_t) sig_len; return true; }
int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; unsigned int sig_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* create and verify a ecdsa signature with every availble curve * (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160) /* drop the curve */ { EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* modify a single byte of the signature */ offset = signature[10] % sig_len; dirt = signature[11]; signature[offset] ^= dirt ? dirt : 1; if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; } ret = 1; builtin_err: if (eckey) EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); if (signature) OPENSSL_free(signature); if (curves) OPENSSL_free(curves); return ret; }
int test_builtin(BIO *out) { size_t n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; BIGNUM *order = NULL; ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; unsigned int sig_len, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } order = BN_new(); if (order == NULL) { goto builtin_err; } /* create and verify a ecdsa signature with every availble curve * (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); static const int kCurveNIDs[] = {NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_undef}; /* now create and verify a signature for every curve */ for (n = 0; kCurveNIDs[n] != NID_undef; n++) { unsigned char dirt, offset; nid = kCurveNIDs[n]; /* create new ecdsa key (== EC_KEY) */ eckey = EC_KEY_new(); if (eckey == NULL) { goto builtin_err; } group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) { goto builtin_err; } if (!EC_KEY_set_group(eckey, group)) { goto builtin_err; } EC_GROUP_free(group); if (!EC_GROUP_get_order(EC_KEY_get0_group(eckey), order, NULL)) { goto builtin_err; } if (BN_num_bits(order) < 160) { /* Too small to test. */ EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ wrong_eckey = EC_KEY_new(); if (wrong_eckey == NULL) { goto builtin_err; } group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) { goto builtin_err; } if (EC_KEY_set_group(wrong_eckey, group) == 0) { goto builtin_err; } EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); signature = OPENSSL_malloc(sig_len); if (signature == NULL) { goto builtin_err; } if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong length */ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* Modify a single byte of the signature: to ensure we don't * garble the ASN1 structure, we read the raw signature and * modify a byte in one of the bignums directly. */ sig_ptr = signature; ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len); if (ecdsa_sig == NULL) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(ecdsa_sig->r); s_len = BN_num_bytes(ecdsa_sig->s); bn_len = BN_num_bytes(order); if (r_len > bn_len || s_len > bn_len) { BIO_printf(out, " failed\n"); goto builtin_err; } buf_len = 2 * bn_len; raw_buf = OPENSSL_malloc(2 * bn_len); if (raw_buf == NULL) { goto builtin_err; } /* Pad the bignums with leading zeroes. */ if (!BN_bn2bin_padded(raw_buf, bn_len, ecdsa_sig->r) || !BN_bn2bin_padded(raw_buf + bn_len, bn_len, ecdsa_sig->s)) { goto builtin_err; } /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL || BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) { goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL || BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) { goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ /* clean bogus errors */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: if (eckey) { EC_KEY_free(eckey); } if (order) { BN_free(order); } if (wrong_eckey) { EC_KEY_free(wrong_eckey); } if (ecdsa_sig) { ECDSA_SIG_free(ecdsa_sig); } if (signature) { OPENSSL_free(signature); } if (raw_buf) { OPENSSL_free(raw_buf); } return ret; }
Blob FilePrivateKeyStorage::sign (const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) { string keyURI = keyName.toUri(); if (!doesKeyExist(keyName, KEY_CLASS_PRIVATE)) throw SecurityException ("FilePrivateKeyStorage::sign: private key doesn't exist"); if (digestAlgorithm != DIGEST_ALGORITHM_SHA256) throw SecurityException ("FilePrivateKeyStorage::sign: Unsupported digest algorithm"); // Read the private key. ifstream file(nameTransform(keyURI, ".pri").c_str()); stringstream base64; base64 << file.rdbuf(); vector<uint8_t> pkcs8Der; fromBase64(base64.str(), pkcs8Der); // The private key is generated by NFD which stores as PKCS #8. Decode it // to find the algorithm OID and the inner private key DER. ptr_lib::shared_ptr<DerNode> parsedNode = DerNode::parse(&pkcs8Der[0], 0); const std::vector<ptr_lib::shared_ptr<DerNode> >& pkcs8Children = parsedNode->getChildren(); // Get the algorithm OID and parameters. const std::vector<ptr_lib::shared_ptr<DerNode> >& algorithmIdChildren = DerNode::getSequence(pkcs8Children, 1).getChildren(); string oidString (dynamic_cast<DerNode::DerOid&>(*algorithmIdChildren[0]).toVal().toRawStr()); ptr_lib::shared_ptr<DerNode> algorithmParameters = algorithmIdChildren[1]; // Get the value of the 3rd child which is the octet string. Blob privateKeyDer = pkcs8Children[2]->toVal(); // Get the digest to sign. uint8_t digest[SHA256_DIGEST_LENGTH]; ndn_digestSha256(data, dataLength, digest); // TODO: use RSA_size, etc. to get the proper size of the signature buffer. uint8_t signatureBits[1000]; unsigned int signatureBitsLength; // Decode the private key and sign. if (oidString == RSA_ENCRYPTION_OID) { // Use a temporary pointer since d2i updates it. const uint8_t* derPointer = privateKeyDer.buf(); rsa_st* privateKey = d2i_RSAPrivateKey(NULL, &derPointer, privateKeyDer.size()); if (!privateKey) throw SecurityException ("FilePrivateKeyStorage::sign: Error decoding the RSA private key DER"); int success = RSA_sign (NID_sha256, digest, sizeof(digest), signatureBits, &signatureBitsLength, privateKey); // Free the private key before checking for success. RSA_free(privateKey); if (!success) throw SecurityException("FilePrivateKeyStorage::sign: Error in RSA_sign"); } else if (oidString == EC_ENCRYPTION_OID) { ec_key_st* privateKey = decodeEcPrivateKey(algorithmParameters, privateKeyDer); int success = ECDSA_sign (NID_sha256, digest, sizeof(digest), signatureBits, &signatureBitsLength, privateKey); // Free the private key before checking for success. EC_KEY_free(privateKey); if (!success) throw SecurityException("FilePrivateKeyStorage::sign: Error in ECDSA_sign"); } else throw SecurityException ("FilePrivateKeyStorage::sign: Unrecognized private key OID"); return Blob(signatureBits, (size_t)signatureBitsLength); }
static int test_builtin(void) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; const BIGNUM *sig_r, *sig_s; BIGNUM *modified_r = NULL, *modified_s = NULL; BIGNUM *unmodified_r = NULL, *unmodified_s = NULL; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!TEST_true(RAND_bytes(digest, 20)) || !TEST_true(RAND_bytes(wrong_digest, 20))) goto builtin_err; /* create and verify a ecdsa signature with every available curve */ /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) || !TEST_true(EC_get_builtin_curves(curves, crv_len))) goto builtin_err; /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4 || nid == NID_X25519) continue; /* create new ecdsa key (== EC_KEY) */ if (!TEST_ptr(eckey = EC_KEY_new()) || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) || !TEST_true(EC_KEY_set_group(eckey, group))) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) { /* drop the curve */ EC_KEY_free(eckey); eckey = NULL; continue; } TEST_info("testing %s", OBJ_nid2sn(nid)); /* create key */ if (!TEST_true(EC_KEY_generate_key(eckey))) goto builtin_err; /* create second key */ if (!TEST_ptr(wrong_eckey = EC_KEY_new()) || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) || !TEST_true(EC_KEY_set_group(wrong_eckey, group))) goto builtin_err; EC_GROUP_free(group); if (!TEST_true(EC_KEY_generate_key(wrong_eckey))) goto builtin_err; /* check key */ if (!TEST_true(EC_KEY_check_key(eckey))) goto builtin_err; /* create signature */ sig_len = ECDSA_size(eckey); if (!TEST_ptr(signature = OPENSSL_malloc(sig_len)) || !TEST_true(ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))) goto builtin_err; /* verify signature */ if (!TEST_int_eq(ECDSA_verify(0, digest, 20, signature, sig_len, eckey), 1)) goto builtin_err; /* verify signature with the wrong key */ if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey), 1)) goto builtin_err; /* wrong digest */ if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey), 1)) goto builtin_err; /* wrong length */ if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey), 1)) goto builtin_err; /* * Modify a single byte of the signature: to ensure we don't garble * the ASN1 structure, we read the raw signature and modify a byte in * one of the bignums directly. */ sig_ptr = signature; if (!TEST_ptr(ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len))) goto builtin_err; ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s); /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(sig_r); s_len = BN_num_bytes(sig_s); bn_len = (degree + 7) / 8; if (!TEST_false(r_len > bn_len) || !TEST_false(s_len > bn_len)) goto builtin_err; buf_len = 2 * bn_len; if (!TEST_ptr(raw_buf = OPENSSL_zalloc(buf_len))) goto builtin_err; BN_bn2bin(sig_r, raw_buf + bn_len - r_len); BN_bn2bin(sig_s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if (!TEST_ptr(modified_sig = ECDSA_SIG_new())) goto builtin_err; if (!TEST_ptr(modified_r = BN_bin2bn(raw_buf, bn_len, NULL)) || !TEST_ptr(modified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) || !TEST_true(ECDSA_SIG_set0(modified_sig, modified_r, modified_s))) { BN_free(modified_r); BN_free(modified_s); goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); if (!TEST_false(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) goto builtin_err; /* Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL)) || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r, unmodified_s))) { BN_free(unmodified_r); BN_free(unmodified_s); goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); if (!TEST_true(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) goto builtin_err; /* cleanup */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; ECDSA_SIG_free(modified_sig); modified_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: EC_KEY_free(eckey); EC_KEY_free(wrong_eckey); ECDSA_SIG_free(ecdsa_sig); ECDSA_SIG_free(modified_sig); OPENSSL_free(signature); OPENSSL_free(raw_buf); OPENSSL_free(curves); return ret; }
void main() { uint8 seed[16]; //seed for DRNG uint8 rndnum[30]; //233-bit random numbers uint32 i, r; ec_key_pair keypair; uint8 Uid[26] = {0x00,0x0d,0x6f,0x00,0x00,0x06,0x7a,0x1f,0x54,0x45,0x53,0x54,0x53,0x45,0x43,0x41,0x01,0x09,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00}; //The following are for ECMQV ec_key_pair keyA1, keyA2, keyB1, keyB2; uint8 skey[30]; //The following are for ECDSA uint32 s[8], t[8]; for(i = 0; i < 16; i++) seed[i] = 0x0; srand((unsigned) time (NULL)); for(i = 0; i < 8; i++) { r = rand(); seed[2*i] = (uint8)r; seed[2*i + 1] = (uint8)(r >> 8); } printf("Seed = ");for(i = 0; i < 16; i++){printf("%02x ",seed[i]);}printf("\n"); //Initialize the DRNG ctr_init(seed); for(i = 0; i < 30; i++) rndnum[i] = 0x0; //ECMQV testing with curve sect233k1 if(ctr_generate(232, rndnum) == 1) key_generation(&keyA1, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyA2, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyB1, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyB2, rndnum, sect233k1); printf("\nTwo key pairs for the user A...\n"); printf("The first private key:\n"); printf(" dA1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.d[7 - i]);}printf("\n"); printf("The first public key:\n"); printf(" QA1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.Qx[7 - i]);}printf("\n"); printf("The second private key:\n"); printf(" dA2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.d[7 - i]);}printf("\n"); printf("The second public key:\n"); printf(" QA2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.Qx[7 - i]);}printf("\n"); printf("\nTwo key pairs for the user B...\n"); printf("The first private key:\n"); printf(" dB1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.d[7 - i]);}printf("\n"); printf("The first public key:\n"); printf(" QB1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.Qx[7 - i]);}printf("\n"); printf("The second private key:\n"); printf(" dB2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.d[7 - i]);}printf("\n"); printf("The second public key:\n"); printf(" QB2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.Qx[7 - i]);}printf("\n"); printf("\nECMQV Key Agreement..."); if(ECMQV(&keyA1, &keyA2, keyB1.Qx, keyB2.Qx, 30, skey, sect233k1) == 1) { printf("The shared key computed by A:\n"); printf(" skA = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); } else { printf("ERROR!\n"); goto L; } if(ECMQV(&keyB1, &keyB2, keyA1.Qx, keyA2.Qx, 30, skey, sect233k1) == 1) { printf("The shared key computed by B:\n"); printf(" skB = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); } else printf("ERROR!\n"); //ECDSA testing with curve sect233k1 printf("\nECDSA Signature Generation...\n"); if(ctr_generate(232, rndnum) == 1) key_generation(&keypair,rndnum, sect233k1); printf("Signer's Private key:\n"); printf(" k = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.d[7 - i]);}printf("\n"); printf("Signer's Public key:\n"); printf(" x = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.Qx[7 - i]);}printf("\n"); printf("Message:\n"); printf("msg = ");for(i = 0; i < 26; i++){printf("%02x",Uid[i]);}printf("\n"); ctr_generate(232, rndnum); if(ECDSA_sign(keypair.d, rndnum, Uid, 26, s, t, sect233k1) == 1) { printf("The signature are:\n"); printf(" r = ");for(i = 0; i < 8; i++){printf("%08x ",s[7 - i]);}printf("\n"); printf(" s = ");for(i = 0; i < 8; i++){printf("%08x ",t[7 - i]);}printf("\n"); } else { printf("ERROR!\n"); goto L; } if(ECDSA_verify(keypair.Qx, Uid, 26, s, t, sect233k1) == 1) printf("The signature is valid!\n"); else printf("The signature is invalid!\n"); L:; }
static int ecdsa_create_signature(hx509_context context, const struct signature_alg *sig_alg, const hx509_private_key signer, const AlgorithmIdentifier *alg, const heim_octet_string *data, AlgorithmIdentifier *signatureAlgorithm, heim_octet_string *sig) { const AlgorithmIdentifier *digest_alg; heim_octet_string indata; const heim_oid *sig_oid; unsigned int siglen; int ret; if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0) _hx509_abort("internal error passing private key to wrong ops"); sig_oid = sig_alg->sig_oid; digest_alg = sig_alg->digest_alg; if (signatureAlgorithm) { ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2); if (ret) { hx509_clear_error_string(context); return ret; } } ret = _hx509_create_signature(context, NULL, digest_alg, data, NULL, &indata); if (ret) goto error; sig->length = ECDSA_size(signer->private_key.ecdsa); sig->data = malloc(sig->length); if (sig->data == NULL) { der_free_octet_string(&indata); ret = ENOMEM; hx509_set_error_string(context, 0, ret, "out of memory"); goto error; } siglen = sig->length; ret = ECDSA_sign(-1, indata.data, indata.length, sig->data, &siglen, signer->private_key.ecdsa); der_free_octet_string(&indata); if (ret != 1) { ret = HX509_CMS_FAILED_CREATE_SIGATURE; hx509_set_error_string(context, 0, ret, "ECDSA sign failed: %d", ret); goto error; } if (siglen > sig->length) _hx509_abort("ECDSA signature prelen longer the output len"); sig->length = siglen; return 0; error: if (signatureAlgorithm) free_AlgorithmIdentifier(signatureAlgorithm); return ret; }