// create a compact signature (65 bytes), which allows reconstructing the used public key // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y bool CKey::SignCompact(uint256 hash, std::vector<unsigned char>& vchSig) { bool fOk = false; ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); if (sig==NULL) return false; vchSig.clear(); vchSig.resize(65,0); int nBitsR = BN_num_bits(sig->r); int nBitsS = BN_num_bits(sig->s); if (nBitsR <= 256 && nBitsS <= 256) { int nRecId = -1; for (int i=0; i<4; i++) { CKey keyRec; keyRec.fSet = true; if (fCompressedPubKey) keyRec.SetCompressedPubKey(); if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) if (keyRec.GetPubKey() == this->GetPubKey()) { nRecId = i; break; } } if (nRecId == -1) { ECDSA_SIG_free(sig); throw key_error("CKey::SignCompact() : unable to construct recoverable key"); } vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0); BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); fOk = true; } ECDSA_SIG_free(sig); return fOk; }
EcdsaSignature BackendOpenSsl::sign_data(const ecdsa256::PrivateKey& key, const ByteBuffer& data) { auto priv_key = internal_private_key(key); auto digest = calculate_digest(data); // sign message data represented by the digest openssl::Signature signature { ECDSA_do_sign(digest.data(), digest.size(), priv_key) }; #if OPENSSL_API_COMPAT < 0x10100000L const BIGNUM* sig_r = signature->r; const BIGNUM* sig_s = signature->s; #else const BIGNUM* sig_r = nullptr; const BIGNUM* sig_s = nullptr; ECDSA_SIG_get0(signature, &sig_r, &sig_s); #endif EcdsaSignature ecdsa_signature; X_Coordinate_Only coordinate; if (sig_r && sig_s) { const size_t len = field_size(PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256); const auto num_bytes_s = BN_num_bytes(sig_s); assert(len >= static_cast<size_t>(num_bytes_s)); ecdsa_signature.s.resize(len, 0x00); BN_bn2bin(sig_s, ecdsa_signature.s.data() + len - num_bytes_s); const auto num_bytes_r = BN_num_bytes(sig_r); assert(len >= static_cast<size_t>(num_bytes_r)); coordinate.x.resize(len, 0x00); BN_bn2bin(sig_r, coordinate.x.data() + len - num_bytes_r); } else { throw openssl::Exception(); } ecdsa_signature.R = std::move(coordinate); return ecdsa_signature; }
int main (int argc, const char * argv[]) { EC_KEY *eckey; unsigned int curve; size_t digest_len; char name[1024], curve_name[200], pubkey[1024], privkey[1024]; if (!read_params(name, 1024, curve_name, 200, pubkey, 1024, privkey, 1024)) return ERR_STDIN_READ; ///*debug*/printf("%s\n%s\n%s\n%s\n", name, curve_name, pubkey, privkey); // Get curve type and digest_len if (strcmp(curve_name, "secp112r1") == 0) { curve = NID_secp112r1; digest_len = 14; } else if (strcmp(curve_name, "secp128r1") == 0) { curve = NID_secp128r1; digest_len = 16; } else if (strcmp(curve_name, "secp160r1") == 0) { curve = NID_secp160r1; digest_len = 20; } else { return ERR_CURVE_UNKNOWN; } eckey = EC_KEY_new_by_curve_name(curve); if (eckey == NULL) return ERR_INIT_KEY; // set public key unsigned char *bin = NULL; size_t len = hex2bin(&bin, pubkey); if (len == 0) return ERR_PUBLIC_KEY_DECODING; const unsigned char *bin_copy = bin; eckey = o2i_ECPublicKey(&eckey, &bin_copy, len); OPENSSL_free(bin); // set private key len = hex2bin(&bin, privkey); if (len == 0) return ERR_PUBLIC_KEY_DECODING; bin_copy = bin; eckey = d2i_ECPrivateKey(&eckey, &bin_copy, len); OPENSSL_free(bin); // check keys if (!EC_KEY_check_key(eckey)) return ERR_WRONG_KEYS; // calculate sha-1 unsigned char digest[digest_len]; el_compute_digest(name, digest, digest_len); // sign ECDSA_SIG *sig = ECDSA_do_sign(digest, digest_len, eckey); if (sig == NULL) return ERR_SIGNING; size_t rlen = BN_num_bytes(sig->r); size_t slen = BN_num_bytes(sig->s); size_t binlen = rlen + slen; bin = OPENSSL_malloc(binlen); bzero(bin, binlen); BN_bn2bin(sig->r, bin); BN_bn2bin(sig->s, bin + rlen); // join two values into bin ECDSA_SIG_free(sig); size_t b32len = el_base32_encode_buffer_size(binlen); char *base32 = OPENSSL_malloc(b32len); bzero(base32, b32len); el_base32_encode(bin, binlen, base32, b32len); printf("%s", base32); OPENSSL_free(bin); OPENSSL_free(base32); return 0; }
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen) { buffer_t *msg = NULL; char *s; int ret; msg = buffer_init(); if (msg == NULL) { // TODO: error check return FALSE; } switch (keypair->type) { case KEY_RSA: // RSA { const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], *sig; u_int slen, dlen, len; int ok, nid = NID_sha1; // ダイジェスト値の計算 EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); slen = RSA_size(keypair->rsa); sig = malloc(slen); if (sig == NULL) goto error; // 電子署名を計算 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa); memset(digest, 'd', sizeof(digest)); if (ok != 1) { // error free(sig); goto error; } // 署名のサイズがバッファより小さい場合、後ろへずらす。先頭はゼロで埋める。 if (len < slen) { u_int diff = slen - len; memmove(sig + diff, sig, len); memset(sig, 0, diff); } else if (len > slen) { free(sig); goto error; } else { // do nothing } s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sig, slen); len = buffer_len(msg); // setting *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { free(sig); goto error; } memcpy(*sigptr, buffer_ptr(msg), len); free(sig); break; } case KEY_DSA: // DSA { DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; u_int rlen, slen, len, dlen; // ダイジェストの計算 EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); // DSA電子署名を計算 sig = DSA_do_sign(digest, dlen, keypair->dsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { goto error; } // BIGNUMからバイナリ値への変換 rlen = BN_num_bytes(sig->r); slen = BN_num_bytes(sig->s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { DSA_SIG_free(sig); goto error; } memset(sigblob, 0, SIGBLOB_LEN); BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); DSA_SIG_free(sig); // setting s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sigblob, sizeof(sigblob)); len = buffer_len(msg); // setting *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { goto error; } memcpy(*sigptr, buffer_ptr(msg), len); break; } case KEY_ECDSA256: // ECDSA case KEY_ECDSA384: case KEY_ECDSA521: { ECDSA_SIG *sig; const EVP_MD *evp_md; EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE]; u_int len, dlen, nid; buffer_t *buf2 = NULL; nid = keytype_to_hash_nid(keypair->type); if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { goto error; } EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { goto error; } buf2 = buffer_init(); if (buf2 == NULL) { // TODO: error check goto error; } buffer_put_bignum2(buf2, sig->r); buffer_put_bignum2(buf2, sig->s); ECDSA_SIG_free(sig); s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2)); buffer_free(buf2); len = buffer_len(msg); *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { goto error; } memcpy(*sigptr, buffer_ptr(msg), len); break; } case KEY_ED25519: ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen); if (ret != 0) goto error; break; default: buffer_free(msg); return FALSE; break; } buffer_free(msg); return TRUE; error: buffer_free(msg); return FALSE; }
/* some tests from the X9.62 draft */ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) { int ret = 0; const char message[] = "abc"; unsigned char digest[20]; unsigned int dgst_len = 0; EVP_MD_CTX md_ctx; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; EVP_MD_CTX_init(&md_ctx); /* get the message digest */ EVP_DigestInit(&md_ctx, EVP_ecdsa()); EVP_DigestUpdate(&md_ctx, (const void *)message, 3); EVP_DigestFinal(&md_ctx, digest, &dgst_len); BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); /* create the key */ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) goto x962_int_err; if (!EC_KEY_generate_key(key)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* create the signature */ signature = ECDSA_do_sign(digest, 20, key); if (signature == NULL) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* compare the created signature with the expected signature */ if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) goto x962_int_err; if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) goto x962_int_err; if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* verify the signature */ if (ECDSA_do_verify(digest, 20, signature, key) != 1) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); ret = 1; x962_int_err: if (!ret) BIO_printf(out, " failed\n"); if (key) EC_KEY_free(key); if (signature) ECDSA_SIG_free(signature); if (r) BN_free(r); if (s) BN_free(s); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
int main(int argc, char **argv) { CK_ULONG nslots; CK_SLOT_ID *pslots = NULL; CK_FUNCTION_LIST *funcs = NULL; CK_UTF8CHAR_PTR opt_pin = NULL; CK_ULONG opt_pin_len = 0; CK_RV rc; CK_ULONG opt_slot = -1; CK_SESSION_HANDLE h_session; char *opt_module = NULL, *opt_dir = NULL; /* struct sockaddr_un sockaddr; */ int long_optind = 0; int fd, verbose = 0; key_id_t *rsa_keys, *ec_keys; CK_ULONG rsa_len = 0, ec_len = 0, i; init_crypto(); while (1) { char c = getopt_long(argc, argv, "d:hp:s:m:v", options, &long_optind); if (c == -1) break; switch (c) { case 'd': opt_dir = optarg; break; case 'p': opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg); if(opt_pin) { opt_pin_len = strlen(optarg); } break; case 's': opt_slot = (CK_SLOT_ID) atoi(optarg); break; case 'm': opt_module = optarg; break; case 'v': verbose = 1; break; case 'h': default: print_usage_and_die(app_name, options, option_help); } } rc = pkcs11_load_init(opt_module, opt_dir, stderr, &funcs); if (rc != CKR_OK) { return rc; } rc = pkcs11_get_slots(funcs, stderr, &pslots, &nslots); if (rc != CKR_OK) { return rc; } if(opt_slot == -1) { if(nslots < 1) { /* No slots */ return -1; } else { opt_slot = pslots[0]; } } else { /* Check selected slot is in pslots */ } fprintf(stderr, "Slot: %ld\n", opt_slot); rc = pkcs11_login_session(funcs, stderr, opt_slot, &h_session, CK_TRUE, CKU_USER, opt_pin, opt_pin_len); if (rc != CKR_OK) { show_error(stderr, "Login", rc); return rc; } load_keys(funcs, h_session, CKK_RSA, &rsa_keys, &rsa_len); load_keys(funcs, h_session, CKK_EC, &ec_keys, &ec_len); /* fd = nw_unix_server("pkcs11d.sock", &sockaddr, 0, 0, 0, 64); */ /* close(fd); */ fd = nw_tcp_server(1234, 0, 64); do { struct sockaddr address; socklen_t a_len = sizeof(address); int s = accept(fd, &address, &a_len); BIO *b = BIO_new_socket(s, BIO_NOCLOSE); BIO *buf = BIO_new(BIO_f_buffer()); b = BIO_push(buf, b); char buffer[4096], sig[4096], keyid[KEY_ID_SIZE + 1]; int l, slen = 0, plen = 0; CK_KEY_TYPE type; CK_ATTRIBUTE_TYPE operation; EVP_PKEY *pkey = NULL; l = BIO_gets(b, buffer, sizeof(buffer)); if(l <= 0) { fprintf(stderr, "Error reading query line\n"); goto end; } if(strncmp(buffer, "POST /sign/rsa/", 15) == 0) { memcpy(keyid, buffer + 15, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_SIGN; } else if(strncmp(buffer, "POST /decrypt/rsa/", 18) == 0) { memcpy(keyid, buffer + 18, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_DECRYPT; } else if(strncmp(buffer, "POST /sign/ec/", 14) == 0) { memcpy(keyid, buffer + 14, KEY_ID_SIZE - 1); type = CKK_EC; operation = CKA_SIGN; } else { goto end; } keyid[KEY_ID_SIZE] = '\0'; l = BIO_gets(b, buffer, sizeof(buffer)); if((l <= 0) || strncmp(buffer, "Content-Length: ", 16) != 0) { fprintf(stderr, "Invalid content length line = %s\n", buffer); goto end; } plen = atoi(buffer + 16); l = BIO_gets(b, buffer, sizeof(buffer)); l = BIO_read(b, buffer, plen); if(l < plen) { fprintf(stderr, "Error reading payload\n"); goto end; } if(type == CKK_RSA) { for(i = 0; (i < rsa_len) && (pkey == NULL); i++) { if(strncmp(rsa_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = rsa_keys[i].key; } } } else if(type == CKK_EC) { for(i = 0; (i < ec_len) && (pkey == NULL); i++) { if(strncmp(ec_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = ec_keys[i].key; } } } if(pkey == NULL) { fprintf(stderr, "Key not found\n"); goto end; } else if(verbose) { fprintf(stderr, "Key '%s'found\n", keyid); } if(type == CKK_RSA && operation == CKA_SIGN) { if(verbose) { fprintf(stderr, "RSA signature operation requested\n"); } l = RSA_private_encrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if(type == CKK_RSA && operation == CKA_DECRYPT) { if(verbose) { fprintf(stderr, "RSA decryption operation requested\n"); } l = RSA_private_decrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if (type == CKK_EC && operation == CKA_SIGN) { unsigned char *ptr = (unsigned char *)sig; ECDSA_SIG *s = ECDSA_do_sign((unsigned char *)buffer, plen, EVP_PKEY_get1_EC_KEY(pkey)); l = i2d_ECDSA_SIG(s, &ptr); ECDSA_SIG_free(s); } else { if(verbose) { fprintf(stderr, "Invalid operation requested\n"); } goto end; } slen = l; if(l <= 0) { if(verbose) { fprintf(stderr, "Error unsuccessful\n"); } goto end; } else if(verbose) { fprintf(stderr, "Operation successful\n"); } BIO_printf(b, "200 Ok\r\n"); BIO_printf(b, "Content-Length: %d\r\n\r\n", slen); l = BIO_write(b, sig, slen); BIO_flush(b); i= 0; /* for(i = 0; i < rsa_len; i++) { BIO_write(b, rsa_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_RSAPrivateKey(b, EVP_PKEY_get1_RSA(rsa_keys[i].key), NULL, NULL, 0, NULL, NULL); } for(i = 0; i < ec_len; i++) { BIO_write(b, ec_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_ECPrivateKey(b, EVP_PKEY_get1_EC_KEY(ec_keys[i].key), NULL, NULL, 0, NULL, NULL); } */ end: close(s); BIO_free(b); } while(1); close(fd); if(opt_pin) { funcs->C_CloseAllSessions(opt_slot); free(opt_pin); } rc = funcs->C_Finalize(NULL); if (rc != CKR_OK) { show_error(stderr, "C_Finalize", rc); return rc; } return rc; }
/* ARGSUSED */ int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t len, dlen; struct sshbuf *b = NULL, *bb = NULL; int ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || (dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) goto out; if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || (ret = sshbuf_put_stringb(b, bb)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sshbuf_ptr(b), len); } if (lenp != NULL) *lenp = len; ret = 0; out: explicit_bzero(digest, sizeof(digest)); if (b != NULL) sshbuf_free(b); if (bb != NULL) sshbuf_free(bb); if (sig != NULL) ECDSA_SIG_free(sig); return ret; }
static bool _cjose_jws_build_sig_ec(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err) { bool retval = false; // ensure jwk is EC if (jwk->kty != CJOSE_JWK_KTY_EC) { CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG); return false; } ec_keydata *keydata = (ec_keydata *)jwk->keydata; EC_KEY *ec = keydata->key; ECDSA_SIG *ecdsa_sig = ECDSA_do_sign(jws->dig, jws->dig_len, ec); if (NULL == ecdsa_sig) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_sig_ec_cleanup; } // allocate buffer for signature switch (keydata->crv) { case CJOSE_JWK_EC_P_256: jws->sig_len = 32 * 2; break; case CJOSE_JWK_EC_P_384: jws->sig_len = 48 * 2; break; case CJOSE_JWK_EC_P_521: jws->sig_len = 66 * 2; break; case CJOSE_JWK_EC_INVALID: jws->sig_len = 0; break; } jws->sig = (uint8_t *)cjose_get_alloc()(jws->sig_len); if (NULL == jws->sig) { CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY); goto _cjose_jws_build_sig_ec_cleanup; } memset(jws->sig, 0, jws->sig_len); const BIGNUM *pr, *ps; #if defined(CJOSE_OPENSSL_11X) ECDSA_SIG_get0(ecdsa_sig, &pr, &ps); #else pr = ecdsa_sig->r; ps = ecdsa_sig->s; #endif int rlen = BN_num_bytes(pr); int slen = BN_num_bytes(ps); BN_bn2bin(pr, jws->sig + jws->sig_len / 2 - rlen); BN_bn2bin(ps, jws->sig + jws->sig_len - slen); // base64url encode signed digest if (!cjose_base64url_encode((const uint8_t *)jws->sig, jws->sig_len, &jws->sig_b64u, &jws->sig_b64u_len, err)) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_sig_ec_cleanup; } retval = true; _cjose_jws_build_sig_ec_cleanup: if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); return retval; }
int BORINGSSL_self_test(void) { static const uint8_t kAESKey[16] = "BoringCrypto Key"; static const uint8_t kAESIV[16] = {0}; static const uint8_t kPlaintext[64] = "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!"; static const uint8_t kAESCBCCiphertext[64] = { 0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b, 0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c, 0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45, 0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad, 0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55, 0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8, #if !defined(BORINGSSL_FIPS_BREAK_AES_CBC) 0x35 #else 0x00 #endif }; static const uint8_t kAESGCMCiphertext[80] = { 0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9, 0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82, 0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa, 0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4, 0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33, 0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61, 0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64, #if !defined(BORINGSSL_FIPS_BREAK_AES_GCM) 0x0d #else 0x00 #endif }; static const DES_cblock kDESKey1 = {"BCMDESK1"}; static const DES_cblock kDESKey2 = {"BCMDESK2"}; static const DES_cblock kDESKey3 = {"BCMDESK3"}; static const DES_cblock kDESIV = {"BCMDESIV"}; static const uint8_t kDESCiphertext[64] = { 0xa4, 0x30, 0x7a, 0x4c, 0x1f, 0x60, 0x16, 0xd7, 0x4f, 0x41, 0xe1, 0xbb, 0x27, 0xc4, 0x27, 0x37, 0xd4, 0x7f, 0xb9, 0x10, 0xf8, 0xbc, 0xaf, 0x93, 0x91, 0xb8, 0x88, 0x24, 0xb1, 0xf6, 0xf8, 0xbd, 0x31, 0x96, 0x06, 0x76, 0xde, 0x32, 0xcd, 0x29, 0x29, 0xba, 0x70, 0x5f, 0xea, 0xc0, 0xcb, 0xde, 0xc7, 0x75, 0x90, 0xe0, 0x0f, 0x5e, 0x2c, 0x0d, 0x49, 0x20, 0xd5, 0x30, 0x83, 0xf8, 0x08, #if !defined(BORINGSSL_FIPS_BREAK_DES) 0x5a #else 0x00 #endif }; static const uint8_t kPlaintextSHA1[20] = { 0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd, 0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8, #if !defined(BORINGSSL_FIPS_BREAK_SHA_1) 0x28 #else 0x00 #endif }; static const uint8_t kPlaintextSHA256[32] = { 0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb, 0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb, 0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, #if !defined(BORINGSSL_FIPS_BREAK_SHA_256) 0x0f #else 0x00 #endif }; static const uint8_t kPlaintextSHA512[64] = { 0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e, 0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74, 0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c, 0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c, 0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b, 0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68, #if !defined(BORINGSSL_FIPS_BREAK_SHA_512) 0x14 #else 0x00 #endif }; static const uint8_t kRSASignature[256] = { 0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33, 0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d, 0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5, 0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6, 0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9, 0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63, 0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29, 0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff, 0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68, 0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8, 0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14, 0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9, 0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3, 0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a, 0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4, 0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5, 0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae, 0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e, 0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b, 0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf, 0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d, 0xd2, 0x0c, 0xb1, #if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG) 0x64 #else 0x00 #endif }; const uint8_t kDRBGEntropy[48] = "BCM Known Answer Test DBRG Initial Entropy "; const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; const uint8_t kDRBGOutput[64] = { 0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5, 0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1, 0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9, 0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32, 0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d, 0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22, #if !defined(BORINGSSL_FIPS_BREAK_DRBG) 0x95 #else 0x00 #endif }; const uint8_t kDRBGEntropy2[48] = "BCM Known Answer Test DBRG Reseed Entropy "; const uint8_t kDRBGReseedOutput[64] = { 0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8, 0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2, 0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6, 0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e, 0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b, 0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4, }; const uint8_t kECDSASigR[32] = { 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, #if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG) 0x0c, #else 0x00, #endif }; const uint8_t kECDSASigS[32] = { 0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6, 0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a, 0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8, }; EVP_AEAD_CTX aead_ctx; EVP_AEAD_CTX_zero(&aead_ctx); RSA *rsa_key = NULL; EC_KEY *ec_key = NULL; ECDSA_SIG *sig = NULL; int ret = 0; AES_KEY aes_key; uint8_t aes_iv[16]; uint8_t output[256]; // AES-CBC Encryption KAT memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { goto err; } AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv, AES_ENCRYPT); if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), "AES-CBC Encryption KAT")) { goto err; } // AES-CBC Decryption KAT memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { goto err; } AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), &aes_key, aes_iv, AES_DECRYPT); if (!check_test(kPlaintext, output, sizeof(kPlaintext), "AES-CBC Decryption KAT")) { goto err; } size_t out_len; uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; OPENSSL_memset(nonce, 0, sizeof(nonce)); if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, sizeof(kAESKey), 0, NULL)) { goto err; } // AES-GCM Encryption KAT if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce, EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), kPlaintext, sizeof(kPlaintext), NULL, 0) || !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), "AES-GCM Encryption KAT")) { goto err; } // AES-GCM Decryption KAT if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce, EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL, 0) || !check_test(kPlaintext, output, sizeof(kPlaintext), "AES-GCM Decryption KAT")) { goto err; } DES_key_schedule des1, des2, des3; DES_cblock des_iv; DES_set_key(&kDESKey1, &des1); DES_set_key(&kDESKey2, &des2); DES_set_key(&kDESKey3, &des3); // 3DES Encryption KAT memcpy(&des_iv, &kDESIV, sizeof(des_iv)); DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2, &des3, &des_iv, DES_ENCRYPT); if (!check_test(kDESCiphertext, output, sizeof(kDESCiphertext), "3DES Encryption KAT")) { goto err; } // 3DES Decryption KAT memcpy(&des_iv, &kDESIV, sizeof(des_iv)); DES_ede3_cbc_encrypt(kDESCiphertext, output, sizeof(kDESCiphertext), &des1, &des2, &des3, &des_iv, DES_DECRYPT); if (!check_test(kPlaintext, output, sizeof(kPlaintext), "3DES Decryption KAT")) { goto err; } // SHA-1 KAT SHA1(kPlaintext, sizeof(kPlaintext), output); if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1), "SHA-1 KAT")) { goto err; } // SHA-256 KAT SHA256(kPlaintext, sizeof(kPlaintext), output); if (!check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), "SHA-256 KAT")) { goto err; } // SHA-512 KAT SHA512(kPlaintext, sizeof(kPlaintext), output); if (!check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), "SHA-512 KAT")) { goto err; } rsa_key = self_test_rsa_key(); if (rsa_key == NULL) { fprintf(stderr, "RSA KeyGen failed\n"); goto err; } // RSA Sign KAT unsigned sig_len; // Disable blinding for the power-on tests because it's not needed and // triggers an entropy draw. rsa_key->flags |= RSA_FLAG_NO_BLINDING; if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output, &sig_len, rsa_key) || !check_test(kRSASignature, output, sizeof(kRSASignature), "RSA Sign KAT")) { goto err; } // RSA Verify KAT if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), kRSASignature, sizeof(kRSASignature), rsa_key)) { fprintf(stderr, "RSA Verify KAT failed.\n"); goto err; } ec_key = self_test_ecdsa_key(); if (ec_key == NULL) { fprintf(stderr, "ECDSA KeyGen failed\n"); goto err; } // ECDSA Sign/Verify PWCT // The 'k' value for ECDSA is fixed to avoid an entropy draw. ec_key->fixed_k = BN_new(); if (ec_key->fixed_k == NULL || !BN_set_word(ec_key->fixed_k, 42)) { fprintf(stderr, "Out of memory\n"); goto err; } sig = ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key); uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)]; uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)]; if (sig == NULL || BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) || !BN_bn2bin(sig->r, ecdsa_r_bytes) || BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) || !BN_bn2bin(sig->s, ecdsa_s_bytes) || !check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") || !check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) { fprintf(stderr, "ECDSA KAT failed.\n"); goto err; } // DBRG KAT CTR_DRBG_STATE drbg; if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, sizeof(kDRBGPersonalization)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, sizeof(kDRBGAD)) || !check_test(kDRBGOutput, output, sizeof(kDRBGOutput), "DBRG Generate KAT") || !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, sizeof(kDRBGAD)) || !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), "DRBG Reseed KAT")) { goto err; } CTR_DRBG_clear(&drbg); CTR_DRBG_STATE kZeroDRBG; memset(&kZeroDRBG, 0, sizeof(kZeroDRBG)); if (!check_test(&kZeroDRBG, &drbg, sizeof(drbg), "DRBG Clear KAT")) { goto err; } ret = 1; err: EVP_AEAD_CTX_cleanup(&aead_ctx); RSA_free(rsa_key); EC_KEY_free(ec_key); ECDSA_SIG_free(sig); return ret; }
int main(int argc, char **argv) { char *prog = basename(argv[0]); EC_GROUP *ec_group = NULL; EC_KEY *ec_key = NULL; BN_CTX *ctx = BN_CTX_new(); const char *id = "*****@*****.**"; unsigned char za[32]; BIGNUM *k = NULL; BIGNUM *x = NULL; ECDSA_SIG *sig = NULL; unsigned char dgst[20] = "abc"; int ret; if (!(ec_group = EC_GROUP_new_by_curve_name(NID_sm2t257v1))) { fprintf(stderr, "%s: no such curve\n", prog); return -1; } if (!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) { fprintf(stderr, "%s: %s %d\n", prog, __FUNCTION__, __LINE__); return -1; } if (!EC_KEY_generate_key(ec_key)) { ERR_print_errors_fp(stderr); return -1; } if ((ret = EC_KEY_compute_za(za, EVP_sha256(), id, strlen(id), ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("Za length = %d\n", ret); if (!(sig = ECDSA_do_sign(dgst, sizeof(dgst), ec_key))) { ERR_print_errors_fp(stderr); return -1; } if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("result = %d\n", ret); if (!ECDSA_sign_setup(ec_key, ctx, &k, &x)) { ERR_print_errors_fp(stderr); return -1; } if (!(sig = ECDSA_do_sign_ex(dgst, sizeof(dgst), k, x, ec_key))) { ERR_print_errors_fp(stderr); return -1; } if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("result = %d\n", ret); return 0; }
int signMessageWithPem(char *message, char *pem, char **signature) { unsigned int meslen = strlen(message); unsigned char *messagebytes = calloc(meslen, sizeof(unsigned char)); int derSigLen = 0; int i = 0; memcpy(messagebytes, message, meslen); EC_KEY *key = NULL; BIO *in = NULL; unsigned char *buffer = NULL; char *sha256ofMsg = calloc(SHA256_HEX_STRING, sizeof(char)); unsigned char *outBytesOfsha256ofMsg = calloc(SHA256_STRING, sizeof(unsigned char)); digestOfBytes(messagebytes, &sha256ofMsg, "sha256", meslen); sha256ofMsg[64] = '\0'; createDataWithHexString(sha256ofMsg, &outBytesOfsha256ofMsg); in = BIO_new(BIO_s_mem()); BIO_puts(in, pem); key = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL); if(key == NULL) { return ERROR; } while(derSigLen < 70 && i < 10) { i++; ECDSA_SIG *sig = ECDSA_do_sign((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, key); int verify = ECDSA_do_verify((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, sig, key); if(verify != 1) { return ERROR; } int buflen = ECDSA_size(key); buffer = OPENSSL_malloc(buflen); derSigLen = i2d_ECDSA_SIG(sig, &buffer); } if(i == 10) return ERROR; char *hexData = calloc(derSigLen, sizeof(char)); memcpy(hexData, buffer-derSigLen, derSigLen); char *hexString = calloc(derSigLen*2+1, sizeof(char)); toHexString(hexData, derSigLen, &hexString); hexString[derSigLen * 2] = '\0'; memcpy(*signature, hexString, (derSigLen*2)+ 1); EC_KEY_free(key); BIO_free_all(in); free(messagebytes); free(sha256ofMsg); free(outBytesOfsha256ofMsg); free(hexData); free(hexString); return NOERROR; }