static int test_EVP_DigestSignInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; unsigned char *sig = NULL; size_t sig_len = 0; EVP_MD_CTX md_ctx, md_ctx_verify; EVP_MD_CTX_init(&md_ctx); EVP_MD_CTX_init(&md_ctx_verify); pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) { goto out; } /* Determine the size of the signature. */ if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) { goto out; } /* Sanity check for testing. */ if (sig_len != (size_t)EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); goto out; } sig = OPENSSL_malloc(sig_len); if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) { goto out; } /* Ensure that the signature round-trips. */ if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { goto out; } ret = 1; out: if (!ret) { ERR_print_errors_fp(stderr); } EVP_MD_CTX_cleanup(&md_ctx); EVP_MD_CTX_cleanup(&md_ctx_verify); EVP_PKEY_free(pkey); if (sig) { OPENSSL_free(sig); } return ret; }
/* test_algorithm_roundtrip signs a message using an already-initialized * |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the * AlgorithmIdentifier to verify the signature. */ static int test_algorithm_roundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { int ret = 0; uint8_t *sig = NULL; size_t sig_len = 0; EVP_MD_CTX md_ctx_verify; X509_ALGOR *algor = NULL; EVP_MD_CTX_init(&md_ctx_verify); if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) { goto out; } /* Save the algorithm. */ algor = X509_ALGOR_new(); if (algor == NULL || !EVP_DigestSignAlgorithm(md_ctx, algor)) { goto out; } /* Determine the size of the signature. */ if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) { goto out; } /* Sanity check for testing. */ if (sig_len != EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); goto out; } sig = malloc(sig_len); if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) { goto out; } /* Ensure that the signature round-trips. */ if (!EVP_DigestVerifyInitFromAlgorithm(&md_ctx_verify, algor, pkey) || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { goto out; } ret = 1; out: EVP_MD_CTX_cleanup(&md_ctx_verify); if (sig) { free(sig); } if (algor) { X509_ALGOR_free(algor); } return ret; }
static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md, const uint8_t *in, size_t in_len) { EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
/* * Generates the mac for the Finished message. Returns the length of the MAC or * 0 on error. */ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, unsigned char *out) { const EVP_MD *md = ssl_handshake_md(s); unsigned char hash[EVP_MAX_MD_SIZE]; size_t hashlen, ret = 0; EVP_PKEY *key = NULL; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { /* SSLfatal() already called */ goto err; } if (str == s->method->ssl3_enc->server_finished_label) { key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, s->server_finished_secret, hashlen); } else if (SSL_IS_FIRST_HANDSHAKE(s)) { key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, s->client_finished_secret, hashlen); } else { unsigned char finsecret[EVP_MAX_MD_SIZE]; if (!tls13_derive_finishedkey(s, ssl_handshake_md(s), s->client_app_traffic_secret, finsecret, hashlen)) goto err; key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret, hashlen); OPENSSL_cleanse(finsecret, sizeof(finsecret)); } if (key == NULL || ctx == NULL || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0 || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0 || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); goto err; } ret = hashlen; err: EVP_PKEY_free(key); EVP_MD_CTX_free(ctx); return ret; }
static int sign_it(const unsigned char *msg, size_t mlen, unsigned char **sig, size_t *slen, EVP_PKEY *pkey) { int result = GS_FAILED; *sig = NULL; *slen = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if (ctx == NULL) return GS_FAILED; const EVP_MD *md = EVP_get_digestbyname("SHA256"); if (md == NULL) goto cleanup; int rc = EVP_DigestInit_ex(ctx, md, NULL); if (rc != 1) goto cleanup; rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey); if (rc != 1) goto cleanup; rc = EVP_DigestSignUpdate(ctx, msg, mlen); if (rc != 1) goto cleanup; size_t req = 0; rc = EVP_DigestSignFinal(ctx, NULL, &req); if (rc != 1 || !(req > 0)) goto cleanup; *sig = OPENSSL_malloc(req); if (*sig == NULL) goto cleanup; *slen = req; rc = EVP_DigestSignFinal(ctx, *sig, slen); if (rc != 1 || req != *slen) goto cleanup; result = GS_OK; cleanup: EVP_MD_CTX_destroy(ctx); ctx = NULL; return result; }
static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md, const uint8_t *in, size_t in_len) { EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; EVP_PKEY_CTX *pctx; int ret = EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) && EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) && EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
static int test_EVP_DigestSignInit(void) { int ret = 0; EVP_PKEY *pkey = NULL; unsigned char *sig = NULL; size_t sig_len = 0; EVP_MD_CTX *md_ctx, *md_ctx_verify = NULL; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()) || !TEST_ptr(md_ctx_verify = EVP_MD_CTX_new()) || !TEST_ptr(pkey = load_example_rsa_key())) goto out; if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey)) || !TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg)))) goto out; /* Determine the size of the signature. */ if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) || !TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey))) goto out; if (!TEST_ptr(sig = OPENSSL_malloc(sig_len)) || !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len))) goto out; /* Ensure that the signature round-trips. */ if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(), NULL, pkey)) || !TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg))) || !TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len))) goto out; ret = 1; out: EVP_MD_CTX_free(md_ctx); EVP_MD_CTX_free(md_ctx_verify); EVP_PKEY_free(pkey); OPENSSL_free(sig); return ret; }
char *compute_and_encode_signature(const grpc_auth_json_key *json_key, const char *signature_algorithm, const char *to_sign) { const EVP_MD *md = openssl_digest_from_algorithm(signature_algorithm); EVP_MD_CTX *md_ctx = NULL; EVP_PKEY *key = EVP_PKEY_new(); size_t sig_len = 0; unsigned char *sig = NULL; char *result = NULL; if (md == NULL) return NULL; md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { gpr_log(GPR_ERROR, "Could not create MD_CTX"); goto end; } EVP_PKEY_set1_RSA(key, json_key->private_key); if (EVP_DigestSignInit(md_ctx, NULL, md, NULL, key) != 1) { gpr_log(GPR_ERROR, "DigestInit failed."); goto end; } if (EVP_DigestSignUpdate(md_ctx, to_sign, strlen(to_sign)) != 1) { gpr_log(GPR_ERROR, "DigestUpdate failed."); goto end; } if (EVP_DigestSignFinal(md_ctx, NULL, &sig_len) != 1) { gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed."); goto end; } sig = gpr_malloc(sig_len); if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) { gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed."); goto end; } result = grpc_base64_encode(sig, sig_len, 1, 0); end: if (key != NULL) EVP_PKEY_free(key); if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); if (sig != NULL) gpr_free(sig); return result; }
QByteArray NvPairingManager::signMessage(QByteArray message) { EVP_MD_CTX *ctx = EVP_MD_CTX_create(); THROW_BAD_ALLOC_IF_NULL(ctx); const EVP_MD *md = EVP_get_digestbyname("SHA256"); THROW_BAD_ALLOC_IF_NULL(md); EVP_DigestInit_ex(ctx, md, NULL); EVP_DigestSignInit(ctx, NULL, md, NULL, m_PrivateKey); EVP_DigestSignUpdate(ctx, reinterpret_cast<unsigned char*>(message.data()), message.length()); size_t signatureLength = 0; EVP_DigestSignFinal(ctx, NULL, &signatureLength); QByteArray signature((int)signatureLength, 0); EVP_DigestSignFinal(ctx, reinterpret_cast<unsigned char*>(signature.data()), &signatureLength); EVP_MD_CTX_destroy(ctx); return signature; }
int tls1_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *seq; EVP_MD_CTX *hash; size_t md_size; int i; EVP_MD_CTX hmac, *mac_ctx; unsigned char buf[5]; int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); int t; if (send) { rec= &(ssl->s3->wrec); seq= &(ssl->s3->write_sequence[0]); hash=ssl->write_hash; } else { rec= &(ssl->s3->rrec); seq= &(ssl->s3->read_sequence[0]); hash=ssl->read_hash; } t=EVP_MD_CTX_size(hash); TINYCLR_SSL_ASSERT(t >= 0); md_size=t; buf[0]=rec->type; buf[1]=(unsigned char)(ssl->version>>8); buf[2]=(unsigned char)(ssl->version); buf[3]=rec->length>>8; buf[4]=rec->length&0xff; /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ if (stream_mac) { mac_ctx = hash; } else { EVP_MD_CTX_copy(&hmac,hash); mac_ctx = &hmac; } if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) { unsigned char dtlsseq[8],*p=dtlsseq; s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); TINYCLR_SSL_MEMCPY (p,&seq[2],6); EVP_DigestSignUpdate(mac_ctx,dtlsseq,8); } else EVP_DigestSignUpdate(mac_ctx,seq,8); EVP_DigestSignUpdate(mac_ctx,buf,5); EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); t=EVP_DigestSignFinal(mac_ctx,md,&md_size); TINYCLR_SSL_ASSERT(t > 0); if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); #ifdef TLS_DEBUG TINYCLR_SSL_PRINTF("sec="); {unsigned int z; for (z=0; z<md_size; z++) TINYCLR_SSL_PRINTF("%02X ",mac_sec[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("seq="); {int z; for (z=0; z<8; z++) TINYCLR_SSL_PRINTF("%02X ",seq[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("buf="); {int z; for (z=0; z<5; z++) TINYCLR_SSL_PRINTF("%02X ",buf[z]); TINYCLR_SSL_PRINTF("\n"); } TINYCLR_SSL_PRINTF("rec="); {unsigned int z; for (z=0; z<rec->length; z++) TINYCLR_SSL_PRINTF("%02X ",buf[z]); TINYCLR_SSL_PRINTF("\n"); } #endif if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER) { for (i=7; i>=0; i--) { ++seq[i]; if (seq[i] != 0) break; } } #ifdef TLS_DEBUG {unsigned int z; for (z=0; z<md_size; z++) TINYCLR_SSL_PRINTF("%02X ",md[z]); TINYCLR_SSL_PRINTF("\n"); } #endif return(md_size); }
/* For OpenSSL >= 1.1.1 the hmac_nif and cmac_nif could be integrated into poly1305 (with 'type' as parameter) */ ERL_NIF_TERM poly1305_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Key, Text) */ #ifdef HAVE_POLY1305 ErlNifBinary key_bin, text, ret_bin; ERL_NIF_TERM ret; EVP_PKEY *key = NULL; EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; const EVP_MD *md = NULL; size_t size; int ret_bin_alloc = 0; ASSERT(argc == 2); if (!enif_inspect_binary(env, argv[0], &key_bin)) goto bad_arg; if (key_bin.size != 32) goto bad_arg; if (!enif_inspect_binary(env, argv[1], &text)) goto bad_arg; if ((key = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305, /*engine*/ NULL, key_bin.data, key_bin.size)) == NULL) goto err; if ((mctx = EVP_MD_CTX_new()) == NULL) goto err; if (EVP_DigestSignInit(mctx, &pctx, md, /*engine*/ NULL, key) != 1) goto err; if (EVP_DigestSignUpdate(mctx, text.data, text.size) != 1) goto err; if (EVP_DigestSignFinal(mctx, NULL, &size) != 1) goto err; if (!enif_alloc_binary(size, &ret_bin)) goto err; ret_bin_alloc = 1; if (EVP_DigestSignFinal(mctx, ret_bin.data, &size) != 1) goto err; if (size != ret_bin.size) { if (!enif_realloc_binary(&ret_bin, size)) goto err; } ret = enif_make_binary(env, &ret_bin); ret_bin_alloc = 0; goto done; bad_arg: return enif_make_badarg(env); err: if (ret_bin_alloc) enif_release_binary(&ret_bin); ret = atom_error; done: if (mctx) EVP_MD_CTX_free(mctx); if (key) EVP_PKEY_free(key); return ret; #else return enif_raise_exception(env, atom_notsup); #endif }
sgx_status_t sgx_rsa3072_sign(const uint8_t * p_data, uint32_t data_size, const sgx_rsa3072_key_t * p_key, sgx_rsa3072_signature_t * p_signature) { if ((p_data == NULL) || (data_size < 1) || (p_key == NULL) || (p_signature == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } sgx_status_t retval = SGX_ERROR_UNEXPECTED; RSA *priv_rsa_key = NULL; EVP_PKEY* priv_pkey = NULL; BIGNUM *n = NULL; BIGNUM *d = NULL; BIGNUM *e = NULL; EVP_MD_CTX* ctx = NULL; const EVP_MD* sha256_md = NULL; size_t siglen = SGX_RSA3072_KEY_SIZE; int ret = 0; CLEAR_OPENSSL_ERROR_QUEUE; do { // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM // n = BN_lebin2bn((const unsigned char *)p_key->mod, sizeof(p_key->mod), 0); if (n == NULL) { break; } // converts the private exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // d = BN_lebin2bn((const unsigned char *)p_key->d, sizeof(p_key->d), 0); if (d == NULL) { break; } // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // e = BN_lebin2bn((const unsigned char *)p_key->e, sizeof(p_key->e), 0); if (e == NULL) { break; } // allocates and initializes an RSA key structure // priv_rsa_key = RSA_new(); if (priv_rsa_key == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // sets the modulus, private exp and public exp values of the RSA key // if (RSA_set0_key(priv_rsa_key, n, e, d) != 1) { BN_clear_free(n); BN_clear_free(d); BN_clear_free(e); break; } // allocates an empty EVP_PKEY structure // priv_pkey = EVP_PKEY_new(); if (priv_pkey == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed // if (EVP_PKEY_assign_RSA(priv_pkey, priv_rsa_key) != 1) { RSA_free(priv_rsa_key); break; } // allocates, initializes and returns a digest context // ctx = EVP_MD_CTX_new(); if (NULL == ctx) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // return EVP_MD structures for SHA256 digest algorithm */ // sha256_md = EVP_sha256(); if (sha256_md == NULL) { break; } // sets up signing context ctx to use digest type // if (EVP_DigestSignInit(ctx, NULL, sha256_md, NULL, priv_pkey) <= 0) { break; } // hashes data_size bytes of data at p_data into the signature context ctx // if (EVP_DigestSignUpdate(ctx, (const void *)p_data, data_size) <= 0) { break; } // signs the data in ctx places the signature in p_signature. // ret = EVP_DigestSignFinal(ctx, (unsigned char *)p_signature, &siglen);//fails if (ret <= 0) { break; } // validates the signature size // if (SGX_RSA3072_KEY_SIZE != siglen) { break; } retval = SGX_SUCCESS; } while (0); if (retval != SGX_SUCCESS) { GET_LAST_OPENSSL_ERROR; } if (ctx) EVP_MD_CTX_free(ctx); if (priv_pkey) { EVP_PKEY_free(priv_pkey); priv_rsa_key = NULL; n = NULL; d = NULL; e = NULL; } if (priv_rsa_key) { RSA_free(priv_rsa_key); n = NULL; d = NULL; e = NULL; } if (n) BN_clear_free(n); if (d) BN_clear_free(d); if (e) BN_clear_free(e); return retval; }
int main() { int ret = -1; int verbose = 0; BIO *out = NULL; int id = EVP_PKEY_SM2; const EVP_MD *md = EVP_sm3(); ENGINE *engine = NULL; EVP_PKEY_CTX *pkctx = NULL; EVP_PKEY *pkey = NULL; EVP_MD_CTX *mdctx = NULL; EVP_CIPHER_CTX *cpctx = NULL; unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world"; size_t dgstlen = 32; unsigned char sig[256]; size_t siglen = sizeof(sig); unsigned char msg[] = "hello world this is the message"; size_t msglen = sizeof(msg); unsigned char cbuf[512]; size_t cbuflen = sizeof(cbuf); unsigned char mbuf[512]; size_t mbuflen = sizeof(mbuf); int len; unsigned int ulen; ERR_load_crypto_strings(); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_PKEY_keygen_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_PKEY_keygen(pkctx, &pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } EVP_PKEY_CTX_free(pkctx); if (0) { EVP_PKEY_print_public(out, pkey, 4, NULL); BIO_printf(out, "\n"); EVP_PKEY_print_private(out, pkey, 4, NULL); BIO_printf(out, "\n"); } if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_PKEY_sign() */ if (!EVP_PKEY_sign_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } bzero(sig, sizeof(sig)); siglen = sizeof(sig); dgstlen = 32; if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { size_t i; printf("signature (%zu bytes) = ", siglen); for (i = 0; i < siglen; i++) { printf("%02X", sig[i]); } printf("\n"); } if (!EVP_PKEY_verify_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("signature verification success!\n"); } /* EVP_PKEY_encrypt() */ if (!EVP_PKEY_encrypt_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } cbuflen = sizeof(cbuf); if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { size_t i; printf("ciphertext (%zu bytes) = ", cbuflen); for (i = 0; i < cbuflen; i++) { printf("%02X", cbuf[i]); } printf("\n"); } if (!EVP_PKEY_decrypt_init(pkctx)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } bzero(mbuf, sizeof(mbuf)); mbuflen = sizeof(mbuf); if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("original message = %s\n", msg); printf("decrypted message = %s\n", mbuf); } /* EVP_PKEY_encrypt_old */ if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { int i; printf("ciphertext (%d bytes) = ", len); for (i = 0; i < len; i++) { printf("%02X", cbuf[i]); } printf("\n"); } bzero(mbuf, sizeof(mbuf)); if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (verbose) { printf("original message = %s\n", msg); printf("decrypted message = %s\n", mbuf); } if (!(mdctx = EVP_MD_CTX_create())) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_SignInit_ex/Update/Final_ex */ if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_SignUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } siglen = ulen; if (verbose) { size_t i; printf("signature (%zu bytes) = ", siglen); for (i = 0; i < siglen; i++) { printf("%02X", sig[i]); } printf("\n"); } if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_VerifyUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_DigestSignInit/Update/Final() */ // FIXME: return values might be different, not just 1 or 0 if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } siglen = sizeof(sig); if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } pkctx = NULL; if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) { ERR_print_errors_fp(stderr); fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) { fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__); goto end; } /* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */ /* EVP_PKEY *pk[NUM_PKEYS] = {0}; unsigned char iv[16]; unsigned char ek[NUM_PKEYS][256]; int eklen[NUM_PKEYS]; RAND_pseudo_bytes(iv, sizeof(iv)); int i; for (i = 0; i < NUM_PKEYS; i++) { } if (!(cpctx = EVP_CIPHER_CTX_new())) { goto end; } if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) { goto end; } if (!EVP_SealUpdate(cpctx, msg, msglen)) { goto end; } if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) { goto end; } */ printf("test success!\n"); ret = 1; end: ERR_print_errors_fp(stderr); return ret; }
static char *ngx_http_acme_sign_json(ngx_conf_t *cf, void *conf, json_t *payload, RSA *key, ngx_str_t replay_nonce, json_t **flattened_jws) { /* * Structure according to RFC7515: * * { * "payload":"<payload contents>", * "protected":"<integrity-protected header contents>", * "header":<non-integrity-protected header contents>, * "signature":"<signature contents>" * } * * Example: * * { * "payload": * "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ", * "protected":"eyJhbGciOiJFUzI1NiJ9", * "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"}, * "signature": * "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q" * } */ /* * ACME restrictions: * The JWS MUST use the Flattened JSON Serialization * The JWS MUST be encoded using UTF-8 * The JWS Header or Protected Header MUST include “alg” and “jwk” fields * The JWS MUST NOT have the value “none” in its “alg” field */ json_t *jwk; json_t *header; ngx_str_t encoded_protected_header, serialized_payload, encoded_payload, tmp; ngx_str_t signing_input, signature, encoded_signature; u_char *tmp_char_p; /* Variables for signing */ EVP_PKEY *evp_key; EVP_MD_CTX *mdctx = NULL; int ret = 0; /* * Encode payload */ serialized_payload = (ngx_str_t)ngx_string_dynamic(json_dumps(payload, 0)); encoded_payload.len = ngx_base64_encoded_length(serialized_payload.len); encoded_payload.data = ngx_alloc(encoded_payload.len, cf->log); ngx_encode_base64url(&encoded_payload, &serialized_payload); println_debug("Signing payload: ", &serialized_payload); /* * Create header */ /* jwk header */ if(ngx_http_acme_create_jwk(cf, conf, key, &jwk) != NGX_CONF_OK) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Failed to create the JWK from the account key"); ngx_free(serialized_payload.data); ngx_free(encoded_payload.data); return NGX_CONF_ERROR; } /* Pack header into JSON */ header = json_pack("{s:s, s:s%, s:o}", "alg", "RS256", "nonce", replay_nonce.data, replay_nonce.len, "jwk", jwk); if(header == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error packing JWS header"); ngx_free(serialized_payload.data); ngx_free(encoded_payload.data); return NGX_CONF_ERROR; } /* Serialize and base64url encode header */ tmp = (ngx_str_t)ngx_string_dynamic(json_dumps(header, 0)); encoded_protected_header.len = ngx_base64_encoded_length(tmp.len); encoded_protected_header.data = ngx_alloc(encoded_protected_header.len, cf->log); ngx_encode_base64url(&encoded_protected_header, &tmp); ngx_free(tmp.data); json_decref(header); /* * Create signature */ /* Create signing input */ /* = ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)) */ signing_input.len = encoded_protected_header.len + strlen(".") + encoded_payload.len; signing_input.data = ngx_alloc(signing_input.len, cf->log); tmp_char_p = ngx_copy(signing_input.data, encoded_protected_header.data, encoded_protected_header.len); tmp_char_p = ngx_copy(tmp_char_p, ".", strlen(".")); tmp_char_p = ngx_copy(tmp_char_p, encoded_payload.data, encoded_payload.len); /* Convert the RSA key to the EVP_PKEY structure */ evp_key = EVP_PKEY_new(); if(evp_key == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature."); return NGX_CONF_ERROR; } if(EVP_PKEY_set1_RSA(evp_key, key) == 0) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature."); return NGX_CONF_ERROR; } /* Create the message digest context */ ret = 0; mdctx = EVP_MD_CTX_create(); if(mdctx == NULL) goto err; /* Initialize the DigestSign operation - SHA-256 has been selected as the message digest function */ if(EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, evp_key) != 1) goto err; /* Call update with the message */ if(EVP_DigestSignUpdate(mdctx, signing_input.data, signing_input.len) != 1) goto err; /* Finalise the DigestSign operation */ /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the */ /* signature. The length is returned in siglen. */ if(EVP_DigestSignFinal(mdctx, NULL, &signature.len) != 1) goto err; /* Allocate memory for the signature */ signature.data = ngx_alloc(signature.len, cf->log); /* Obtain the signature */ if(EVP_DigestSignFinal(mdctx, signature.data, &signature.len) != 1) goto err; /* Success */ ret = 1; err: if(ret != 1) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error signing the message digest for the JWS signature. OpenSSL error 0x%xl", ERR_get_error()); return NGX_CONF_ERROR; } /* Clean up */ EVP_MD_CTX_destroy(mdctx); EVP_PKEY_free(evp_key); /* base64url encode the signature */ encoded_signature.len = ngx_base64_encoded_length(signature.len); encoded_signature.data = ngx_alloc(encoded_signature.len, cf->log); ngx_encode_base64url(&encoded_signature, &signature); ngx_free(signature.data); /* * Create flattened JWS serialization */ *flattened_jws = json_pack("{s:s%,s:s%,s:s%}", "payload", encoded_payload.data, encoded_payload.len, "protected", encoded_protected_header.data, encoded_protected_header.len, "signature", encoded_signature.data, encoded_signature.len ); ngx_free(serialized_payload.data); // TODO (KK) Maybe this is too early for a free since the strings will be used in the flattened JWS (but when to free then?) ngx_free(encoded_payload.data); ngx_free(encoded_protected_header.data); ngx_free(encoded_signature.data); if(*flattened_jws == NULL) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Error serializing flattened JWS"); return NGX_CONF_ERROR; } return NGX_CONF_OK; } /* ngx_http_acme_sign_json */
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) { const EVP_MD *type; EVP_PKEY *pkey; unsigned char *buf_in = NULL, *buf_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype; int rv; type = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (!type || !pkey) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (pkey->ameth->item_sign) { rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); if (rv == 1) outl = signature->length; /*- * Return value meanings: * <=0: error. * 1: method does everything. * 2: carry on as normal. * 3: ASN1 method sets algorithm identifiers: just sign. */ if (rv <= 0) ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); if (rv <= 1) goto err; } else rv = 2; if (rv == 2) { if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { if (!pkey->ameth || !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey->ameth->pkey_id)) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } } else signid = type->pkey_type; if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) paramtype = V_ASN1_NULL; else paramtype = V_ASN1_UNDEF; if (algor1) X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); if (algor2) X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); } inl = ASN1_item_i2d(asn, &buf_in, it); outll = outl = EVP_PKEY_size(pkey); buf_out = OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestSignUpdate(ctx, buf_in, inl) || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); goto err; } if (signature->data != NULL) OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_cleanup(ctx); if (buf_in != NULL) { OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) { OPENSSL_cleanse((char *)buf_out, outll); OPENSSL_free(buf_out); } return (outl); }
static int tls1_prf_P_hash(const EVP_MD *md, const unsigned char *sec, size_t sec_len, const unsigned char *seed, size_t seed_len, unsigned char *out, size_t olen) { int chunk; EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL; EVP_PKEY *mac_key = NULL; unsigned char A1[EVP_MAX_MD_SIZE]; size_t A1_len; int ret = 0; chunk = EVP_MD_size(md); if (!ossl_assert(chunk > 0)) goto err; ctx = EVP_MD_CTX_new(); ctx_tmp = EVP_MD_CTX_new(); ctx_init = EVP_MD_CTX_new(); if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL) goto err; EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); mac_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len); if (mac_key == NULL) goto err; if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key)) goto err; if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)) goto err; if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len)) goto err; if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) goto err; for (;;) { /* Reinit mac contexts */ if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)) goto err; if (!EVP_DigestSignUpdate(ctx, A1, A1_len)) goto err; if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx)) goto err; if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len)) goto err; if (olen > (size_t)chunk) { size_t mac_len; if (!EVP_DigestSignFinal(ctx, out, &mac_len)) goto err; out += mac_len; olen -= mac_len; /* calc the next A1 value */ if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len)) goto err; } else { /* last one */ if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) goto err; memcpy(out, A1, olen); break; } } ret = 1; err: EVP_PKEY_free(mac_key); EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx_tmp); EVP_MD_CTX_free(ctx_init); OPENSSL_cleanse(A1, sizeof(A1)); return ret; }
/* seed1 through seed5 are virtually concatenated */ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, unsigned char *out, int olen) { int chunk; size_t j; EVP_MD_CTX ctx, ctx_tmp; EVP_PKEY *mac_key; unsigned char A1[EVP_MAX_MD_SIZE]; size_t A1_len; int ret = 0; chunk=EVP_MD_size(md); OPENSSL_assert(chunk >= 0); EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&ctx_tmp); EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); if (!mac_key) goto err; if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key)) goto err; if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key)) goto err; if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len)) goto err; if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len)) goto err; if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len)) goto err; if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len)) goto err; if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len)) goto err; if (!EVP_DigestSignFinal(&ctx,A1,&A1_len)) goto err; for (;;) { /* Reinit mac contexts */ if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key)) goto err; if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key)) goto err; if (!EVP_DigestSignUpdate(&ctx,A1,A1_len)) goto err; if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len)) goto err; if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len)) goto err; if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len)) goto err; if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len)) goto err; if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len)) goto err; if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len)) goto err; if (olen > chunk) { if (!EVP_DigestSignFinal(&ctx,out,&j)) goto err; out+=j; olen-=j; /* calc the next A1 value */ if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len)) goto err; } else /* last one */ { if (!EVP_DigestSignFinal(&ctx,A1,&A1_len)) goto err; memcpy(out,A1,olen); break; } } ret = 1; err: EVP_PKEY_free(mac_key); EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx_tmp); OPENSSL_cleanse(A1,sizeof(A1)); return ret; }
/** * * \brief Generates a digest then sends the digest to the * ATECCX08 chip to generate an ECDSA signature using * private key from TLS_SLOT_AUTH_PRIV slot. The private * key is always stays in the chip: OpenSSL (nor any * other software) has no way to read it. * * \param[in] ctx - a pointer to the EVP_MD_CTX structure * \param[in] it - a pointer to the ASN1_ITEM structure * \param[in] asn - a void pointer to the parameter * \param[in] algor1 - a pointer to the X509_ALGOR structure * \param[in] algor2 - a pointer to the X509_ALGOR structure * \param[out] signature - a pointer to the ASN1_BIT_STRING * structure to return the signature in the ASN.1 format * \return 1 for success */ int eccx08_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature) { int rc = 0; int ret = 0; const EVP_MD *type; EVP_PKEY *pkey; uint8_t *buf_in = NULL, *buf_out = NULL; uint8_t *sig_in = NULL, *sig_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype; uint8_t slotid = TLS_SLOT_AUTH_PRIV; ATCA_STATUS status = ATCA_GEN_FAIL; extern ECDSA_METHOD eccx08_ecdsa; type = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (!type || !pkey) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { if (!pkey->ameth || !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey->ameth->pkey_id)) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } } else signid = type->pkey_type; if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) paramtype = V_ASN1_NULL; else paramtype = V_ASN1_UNDEF; if (algor1) X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); if (algor2) X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); inl = ASN1_item_i2d(asn, &buf_in, it); outll = outl = EVP_PKEY_size(pkey); buf_out = OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); goto done; } #ifdef USE_ECCX08 eccx08_debug("eccx08_item_sign() - HW\n"); ret = EVP_DigestUpdate(ctx, buf_in, inl); if (!ret) goto done; ret = EVP_DigestFinal(ctx, buf_out, (unsigned int *)&outl); if (!ret) goto done; sig_in = OPENSSL_malloc((unsigned int)outll); // source of crash sig_out = sig_in; if (sig_in == NULL) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); goto done; } ECDSA_SIG *ecdsasig; ecdsasig = eccx08_ecdsa.ecdsa_do_sign(buf_out, outl, NULL, NULL, pkey->pkey.ec); if (ecdsasig == NULL) goto done; outl = i2d_ECDSA_SIG(ecdsasig, &sig_in); if (ecdsasig->r) { BN_free(ecdsasig->r); ecdsasig->r = NULL; } if (ecdsasig->s) { BN_free(ecdsasig->s); ecdsasig->s = NULL; } ECDSA_SIG_free(ecdsasig); #else // USE_ECCX08 eccx08_debug("eccx08_item_sign() - SW\n"); if (!EVP_DigestSignUpdate(ctx, buf_in, inl) || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); goto done; } #endif // USE_ECCX08 if (signature->data != NULL) { OPENSSL_free(signature->data); } #ifdef USE_ECCX08 signature->data = sig_out; sig_out = NULL; #else signature->data = buf_out; buf_out = NULL; #endif signature->length = outl; /* * ASN1_item_sign_ctx() in a_sign.c comment (just copy it here): * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; rc = 1; done: EVP_MD_CTX_cleanup(ctx); if (buf_in != NULL) { OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) { OPENSSL_cleanse((char *)buf_out, outll); OPENSSL_free(buf_out); } if (sig_out != NULL) { OPENSSL_cleanse((char *)sig_out, outll); OPENSSL_free(sig_out); } return (rc); }
static int test_EVP_SM2(void) { int ret = 0; EVP_PKEY *pkey = NULL; EVP_PKEY *params = NULL; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *kctx = NULL; EVP_PKEY_CTX *sctx = NULL; size_t sig_len = 0; unsigned char *sig = NULL; EVP_MD_CTX *md_ctx = NULL; EVP_MD_CTX *md_ctx_verify = NULL; EVP_PKEY_CTX *cctx = NULL; uint8_t ciphertext[128]; size_t ctext_len = sizeof(ciphertext); uint8_t plaintext[8]; size_t ptext_len = sizeof(plaintext); uint8_t sm2_id[] = {1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r'}; pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); if (!TEST_ptr(pctx)) goto done; if (!TEST_true(EVP_PKEY_paramgen_init(pctx) == 1)) goto done; if (!TEST_true(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2))) goto done; if (!TEST_true(EVP_PKEY_paramgen(pctx, ¶ms))) goto done; kctx = EVP_PKEY_CTX_new(params, NULL); if (!TEST_ptr(kctx)) goto done; if (!TEST_true(EVP_PKEY_keygen_init(kctx))) goto done; if (!TEST_true(EVP_PKEY_keygen(kctx, &pkey))) goto done; if (!TEST_true(EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))) goto done; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())) goto done; if (!TEST_ptr(md_ctx_verify = EVP_MD_CTX_new())) goto done; if (!TEST_ptr(sctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx); EVP_MD_CTX_set_pkey_ctx(md_ctx_verify, sctx); if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(sctx, sm2_id, sizeof(sm2_id)), 0)) goto done; if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey))) goto done; if(!TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg)))) goto done; /* Determine the size of the signature. */ if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len))) goto done; if (!TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey))) goto done; if (!TEST_ptr(sig = OPENSSL_malloc(sig_len))) goto done; if (!TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len))) goto done; /* Ensure that the signature round-trips. */ if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sm3(), NULL, pkey))) goto done; if (!TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg)))) goto done; if (!TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len))) goto done; /* now check encryption/decryption */ if (!TEST_ptr(cctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; if (!TEST_true(EVP_PKEY_encrypt_init(cctx))) goto done; if (!TEST_true(EVP_PKEY_encrypt(cctx, ciphertext, &ctext_len, kMsg, sizeof(kMsg)))) goto done; if (!TEST_true(EVP_PKEY_decrypt_init(cctx))) goto done; if (!TEST_true(EVP_PKEY_decrypt(cctx, plaintext, &ptext_len, ciphertext, ctext_len))) goto done; if (!TEST_true(ptext_len == sizeof(kMsg))) goto done; if (!TEST_true(memcmp(plaintext, kMsg, sizeof(kMsg)) == 0)) goto done; ret = 1; done: EVP_PKEY_CTX_free(pctx); EVP_PKEY_CTX_free(kctx); EVP_PKEY_CTX_free(sctx); EVP_PKEY_CTX_free(cctx); EVP_PKEY_free(pkey); EVP_PKEY_free(params); EVP_MD_CTX_free(md_ctx); EVP_MD_CTX_free(md_ctx_verify); OPENSSL_free(sig); return ret; }
static int s2n_evp_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size) { GUARD_OSSL(EVP_DigestSignUpdate(ws->tls.p_hash.evp_hmac.evp_digest.ctx, data, (size_t)size), S2N_ERR_P_HASH_UPDATE_FAILED); return 0; }
int jwt_sign_sha_pem(jwt_t *jwt, char **out, unsigned int *len, const char *str) { EVP_MD_CTX *mdctx = NULL; ECDSA_SIG *ec_sig = NULL; const BIGNUM *ec_sig_r = NULL; const BIGNUM *ec_sig_s = NULL; BIO *bufkey = NULL; const EVP_MD *alg; int type; EVP_PKEY *pkey = NULL; int pkey_type; unsigned char *sig; int ret = 0; size_t slen; switch (jwt->alg) { /* RSA */ case JWT_ALG_RS256: alg = EVP_sha256(); type = EVP_PKEY_RSA; break; case JWT_ALG_RS384: alg = EVP_sha384(); type = EVP_PKEY_RSA; break; case JWT_ALG_RS512: alg = EVP_sha512(); type = EVP_PKEY_RSA; break; /* ECC */ case JWT_ALG_ES256: alg = EVP_sha256(); type = EVP_PKEY_EC; break; case JWT_ALG_ES384: alg = EVP_sha384(); type = EVP_PKEY_EC; break; case JWT_ALG_ES512: alg = EVP_sha512(); type = EVP_PKEY_EC; break; default: return EINVAL; } bufkey = BIO_new_mem_buf(jwt->key, jwt->key_len); if (bufkey == NULL) SIGN_ERROR(ENOMEM); /* This uses OpenSSL's default passphrase callback if needed. The * library caller can override this in many ways, all of which are * outside of the scope of LibJWT and this is documented in jwt.h. */ pkey = PEM_read_bio_PrivateKey(bufkey, NULL, NULL, NULL); if (pkey == NULL) SIGN_ERROR(EINVAL); pkey_type = EVP_PKEY_id(pkey); if (pkey_type != type) SIGN_ERROR(EINVAL); mdctx = EVP_MD_CTX_create(); if (mdctx == NULL) SIGN_ERROR(ENOMEM); /* Initialize the DigestSign operation using alg */ if (EVP_DigestSignInit(mdctx, NULL, alg, NULL, pkey) != 1) SIGN_ERROR(EINVAL); /* Call update with the message */ if (EVP_DigestSignUpdate(mdctx, str, strlen(str)) != 1) SIGN_ERROR(EINVAL); /* First, call EVP_DigestSignFinal with a NULL sig parameter to get length * of sig. Length is returned in slen */ if (EVP_DigestSignFinal(mdctx, NULL, &slen) != 1) SIGN_ERROR(EINVAL); /* Allocate memory for signature based on returned size */ sig = alloca(slen); if (sig == NULL) SIGN_ERROR(ENOMEM); /* Get the signature */ if (EVP_DigestSignFinal(mdctx, sig, &slen) != 1) SIGN_ERROR(EINVAL); if (pkey_type != EVP_PKEY_EC) { *out = malloc(slen); if (*out == NULL) SIGN_ERROR(ENOMEM); memcpy(*out, sig, slen); *len = slen; } else { unsigned int degree, bn_len, r_len, s_len, buf_len; unsigned char *raw_buf; EC_KEY *ec_key; /* For EC we need to convert to a raw format of R/S. */ /* Get the actual ec_key */ ec_key = EVP_PKEY_get1_EC_KEY(pkey); if (ec_key == NULL) SIGN_ERROR(ENOMEM); degree = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key)); EC_KEY_free(ec_key); /* Get the sig from the DER encoded version. */ ec_sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&sig, slen); if (ec_sig == NULL) SIGN_ERROR(ENOMEM); ECDSA_SIG_get0(ec_sig, &ec_sig_r, &ec_sig_s); r_len = BN_num_bytes(ec_sig_r); s_len = BN_num_bytes(ec_sig_s); bn_len = (degree + 7) / 8; if ((r_len > bn_len) || (s_len > bn_len)) SIGN_ERROR(EINVAL); buf_len = 2 * bn_len; raw_buf = alloca(buf_len); if (raw_buf == NULL) SIGN_ERROR(ENOMEM); /* Pad the bignums with leading zeroes. */ memset(raw_buf, 0, buf_len); BN_bn2bin(ec_sig_r, raw_buf + bn_len - r_len); BN_bn2bin(ec_sig_s, raw_buf + buf_len - s_len); *out = malloc(buf_len); if (*out == NULL) SIGN_ERROR(ENOMEM); memcpy(*out, raw_buf, buf_len); *len = buf_len; } jwt_sign_sha_pem_done: if (bufkey) BIO_free(bufkey); if (pkey) EVP_PKEY_free(pkey); if (mdctx) EVP_MD_CTX_destroy(mdctx); if (ec_sig) ECDSA_SIG_free(ec_sig); return ret; }
int sign_it(const byte* msg, size_t mlen, byte** sig, size_t* slen, EVP_PKEY* pkey) { /* Returned to caller */ int result = -1; if(!msg || !mlen || !sig || !pkey) { assert(0); return -1; } if(*sig) OPENSSL_free(*sig); *sig = NULL; *slen = 0; EVP_MD_CTX* ctx = NULL; do { ctx = EVP_MD_CTX_create(); assert(ctx != NULL); if(ctx == NULL) { printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } const EVP_MD* md = EVP_get_digestbyname(hn); assert(md != NULL); if(md == NULL) { printf("EVP_get_digestbyname failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } int rc = EVP_DigestInit_ex(ctx, md, NULL); assert(rc == 1); if(rc != 1) { printf("EVP_DigestInit_ex failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey); assert(rc == 1); if(rc != 1) { printf("EVP_DigestSignInit failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } rc = EVP_DigestSignUpdate(ctx, msg, mlen); assert(rc == 1); if(rc != 1) { printf("EVP_DigestSignUpdate failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } size_t req = 0; rc = EVP_DigestSignFinal(ctx, NULL, &req); assert(rc == 1); if(rc != 1) { printf("EVP_DigestSignFinal failed (1), error 0x%lx\n", ERR_get_error()); break; /* failed */ } assert(req > 0); if(!(req > 0)) { printf("EVP_DigestSignFinal failed (2), error 0x%lx\n", ERR_get_error()); break; /* failed */ } *sig = OPENSSL_malloc(req); assert(*sig != NULL); if(*sig == NULL) { printf("OPENSSL_malloc failed, error 0x%lx\n", ERR_get_error()); break; /* failed */ } *slen = req; rc = EVP_DigestSignFinal(ctx, *sig, slen); assert(rc == 1); if(rc != 1) { printf("EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n", rc, ERR_get_error()); break; /* failed */ } assert(req == *slen); if(rc != 1) { printf("EVP_DigestSignFinal failed, mismatched signature sizes %ld, %ld", req, *slen); break; /* failed */ } result = 0; } while(0); if(ctx) { EVP_MD_CTX_destroy(ctx); ctx = NULL; } return !!result; }
int process_files(char **parameters, int param_count){ int i, success = 0; size_t siglen; long int filesize=0, bytes_written=0; unsigned char *signature, *file_mem; char *boincname, *filename; EVP_MD_CTX *mdctx = NULL; FILE *current_file; BIO *b64, *bio_out; printf("Boinc filename Filename Status\n"); printf("--------------------------------------------------------\n"); for(i = 0; i<param_count; i+=2){ boincname = parameters[i]; filename = parameters[i+1]; printf("%-18.18s %-18.18s ", boincname, filename); if(!(mdctx = EVP_MD_CTX_create())) goto err; if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, private_key)) goto err; /* Open file and get size */ current_file = fopen(filename, "rb"); if(current_file == NULL) {print_error("file_signing", "unable to open file", filename); goto err;} fseek(current_file, 0L, SEEK_END); filesize = ftell(current_file); file_mem = (unsigned char *)OPENSSL_malloc(filesize); if(file_mem == NULL) {print_error("file_signing", "unable to reserve memory for file", filename); goto err;} fseek(current_file, 0L, SEEK_SET); //rewind to beginning of file /* read file to memory */ bytes_written = fread(file_mem, 1, filesize, current_file); if(bytes_written != filesize){ if(ferror(current_file)) {print_error("file_signing", "Error reading file", filename); goto err;} else if(feof(current_file)) {printf("File: %s wrote %li of filesize %li", filename, bytes_written, filesize); goto err;} else {print_error("file_signing", "something strange happened", filename); goto err;} } if(1 != EVP_DigestSignUpdate(mdctx, file_mem, filesize)) goto err; if(1 != EVP_DigestSignFinal(mdctx, NULL, &siglen)) goto err; // Get signature size if(!(signature = OPENSSL_malloc(sizeof(unsigned char) * siglen))) goto err; if(1 != EVP_DigestSignFinal(mdctx, signature, &siglen)) goto err; fwrite(boincname, sizeof(char), strlen(boincname), outputfile); fputc(' ', outputfile); b64 = BIO_new(BIO_f_base64()); bio_out = BIO_new_fp(outputfile, BIO_NOCLOSE); BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); BIO_push(b64, bio_out); BIO_write(b64, signature, sizeof(unsigned char) * siglen); BIO_flush(b64); BIO_free_all(b64); fputc('\n', outputfile); success = 1; printf("%-18.18s\n", "Success!"); err: if(mdctx) EVP_MD_CTX_destroy(mdctx); if(current_file) fclose(current_file); if(file_mem) OPENSSL_free(file_mem); if(signature) OPENSSL_free(signature); if(!success) printf("%-18.18s\n", "Failed!"); } }
static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx, const EVP_MD *md, EVP_PKEY *pkey, BIO *in, unsigned char *sig, int siglen, unsigned char **out, size_t *poutlen) { int rv = 0; EVP_MD_CTX *mctx = NULL; unsigned char tbuf[TBUF_MAXSIZE]; int tbuf_len = 0; if ((mctx = EVP_MD_CTX_new()) == NULL) { BIO_printf(bio_err, "Error: out of memory\n"); return rv; } EVP_MD_CTX_set_pkey_ctx(mctx, ctx); switch(pkey_op) { case EVP_PKEY_OP_VERIFY: if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1) goto end; for (;;) { tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); if (tbuf_len == 0) break; if (tbuf_len < 0) { BIO_printf(bio_err, "Error reading raw input data\n"); goto end; } rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)tbuf_len); if (rv != 1) { BIO_printf(bio_err, "Error verifying raw input data\n"); goto end; } } rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); break; case EVP_PKEY_OP_SIGN: if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1) goto end; for (;;) { tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); if (tbuf_len == 0) break; if (tbuf_len < 0) { BIO_printf(bio_err, "Error reading raw input data\n"); goto end; } rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)tbuf_len); if (rv != 1) { BIO_printf(bio_err, "Error signing raw input data\n"); goto end; } } rv = EVP_DigestSignFinal(mctx, NULL, poutlen); if (rv == 1 && out != NULL) { *out = app_malloc(*poutlen, "buffer output"); rv = EVP_DigestSignFinal(mctx, *out, poutlen); } break; } end: EVP_MD_CTX_free(mctx); return rv; }