int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, const char *algname, ENGINE *e, int do_param) { EVP_PKEY_CTX *ctx = NULL; const EVP_PKEY_ASN1_METHOD *ameth; ENGINE *tmpeng = NULL; int pkey_id; if (*pctx) { BIO_puts(err, "Algorithm already set!\n"); return 0; } ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); #ifndef OPENSSL_NO_ENGINE if (!ameth && e) ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); #endif if (!ameth) { BIO_printf(bio_err, "Algorithm %s not found\n", algname); return 0; } ERR_clear_error(); EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); #ifndef OPENSSL_NO_ENGINE if (tmpeng) ENGINE_finish(tmpeng); #endif ctx = EVP_PKEY_CTX_new_id(pkey_id, e); if (!ctx) goto err; if (do_param) { if (EVP_PKEY_paramgen_init(ctx) <= 0) goto err; } else { if (EVP_PKEY_keygen_init(ctx) <= 0) goto err; } *pctx = ctx; return 1; err: BIO_printf(err, "Error initializing %s context\n", algname); ERR_print_errors(err); if (ctx) EVP_PKEY_CTX_free(ctx); return 0; }
/* Create ephemeral key and initialise context based on it */ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *ekey = NULL; int rv = 0; pctx = EVP_PKEY_CTX_new(pk, NULL); if (!pctx) goto err; if (EVP_PKEY_keygen_init(pctx) <= 0) goto err; if (EVP_PKEY_keygen(pctx, &ekey) <= 0) goto err; EVP_PKEY_CTX_free(pctx); pctx = EVP_PKEY_CTX_new(ekey, NULL); if (!pctx) goto err; if (EVP_PKEY_derive_init(pctx) <= 0) goto err; kari->pctx = pctx; rv = 1; err: if (!rv) EVP_PKEY_CTX_free(pctx); EVP_PKEY_free(ekey); return rv; }
static isc_result_t opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { EVP_PKEY_CTX *ctx; union { void *dptr; void (*fptr)(int); } u; EVP_PKEY *pkey = NULL; UNUSED(unused); ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) goto err; if (callback != NULL) { u.fptr = callback; EVP_PKEY_CTX_set_app_data(ctx, u.dptr); EVP_PKEY_CTX_set_cb(ctx, &progress_cb); } if (EVP_PKEY_keygen_init(ctx) <= 0) goto err; if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) goto err; if (EVP_PKEY_keygen(ctx, &pkey) <= 0) goto err; key->keydata.pkey = pkey; EVP_PKEY_CTX_free(ctx); return (ISC_R_SUCCESS); err: if (pkey != NULL) EVP_PKEY_free(pkey); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); }
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key, size_t mac_key_len) { EVP_PKEY_CTX *mac_ctx = NULL; EVP_PKEY *ret = NULL; mac_ctx = EVP_PKEY_CTX_new_id(type, e); if (!mac_ctx) { return NULL; } if (!EVP_PKEY_keygen_init(mac_ctx) || !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len, (uint8_t *)mac_key) || !EVP_PKEY_keygen(mac_ctx, &ret)) { ret = NULL; goto merr; } merr: if (mac_ctx) { EVP_PKEY_CTX_free(mac_ctx); } return ret; }
static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) { BIO *pbio; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; if (*pctx) { BIO_puts(err, "Parameters already set!\n"); return 0; } pbio = BIO_new_file(file, "r"); if (!pbio) { BIO_printf(err, "Can't open parameter file %s\n", file); return 0; } pkey = PEM_read_bio_Parameters(pbio, NULL); BIO_free(pbio); if (!pkey) { BIO_printf(bio_err, "Error reading parameter file %s\n", file); return 0; } ctx = EVP_PKEY_CTX_new(pkey, e); if (!ctx) goto err; if (EVP_PKEY_keygen_init(ctx) <= 0) goto err; EVP_PKEY_free(pkey); *pctx = ctx; return 1; err: BIO_puts(err, "Error initializing context\n"); ERR_print_errors(err); if (ctx) EVP_PKEY_CTX_free(ctx); if (pkey) EVP_PKEY_free(pkey); return 0; }
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen) { EVP_PKEY_CTX *mac_ctx = NULL; EVP_PKEY *mac_key = NULL; mac_ctx = EVP_PKEY_CTX_new_id(type, e); if (!mac_ctx) return NULL; if (EVP_PKEY_keygen_init(mac_ctx) <= 0) goto merr; if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0) goto merr; if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) goto merr; merr: EVP_PKEY_CTX_free(mac_ctx); return mac_key; }
int init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, const char *algname, int do_param) { EVP_PKEY_CTX *ctx = NULL; const EVP_PKEY_ASN1_METHOD *ameth; int pkey_id; if (*pctx) { BIO_puts(err, "Algorithm already set!\n"); return 0; } ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1); if (!ameth) { BIO_printf(bio_err, "Algorithm %s not found\n", algname); return 0; } ERR_clear_error(); EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL); if (!ctx) goto err; if (do_param) { if (EVP_PKEY_paramgen_init(ctx) <= 0) goto err; } else { if (EVP_PKEY_keygen_init(ctx) <= 0) goto err; } *pctx = ctx; return 1; err: BIO_printf(err, "Error initializing %s context\n", algname); ERR_print_errors(err); if (ctx) EVP_PKEY_CTX_free(ctx); return 0; }
soter_status_t soter_rsa_gen_key(EVP_PKEY_CTX *pkey_ctx) { /* it is copy-paste from /src/soter/openssl/soter_asym_cipher.c */ BIGNUM *pub_exp; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx); if (!pkey){ return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_RSA != EVP_PKEY_id(pkey)){ return SOTER_INVALID_PARAMETER; } if (!EVP_PKEY_keygen_init(pkey_ctx)){ return SOTER_INVALID_PARAMETER; } /* Although it seems that OpenSSL/LibreSSL use 0x10001 as default public exponent, we will set it explicitly just in case */ pub_exp = BN_new(); if (!pub_exp){ return SOTER_NO_MEMORY; } if (!BN_set_word(pub_exp, RSA_F4)){ BN_free(pub_exp); return SOTER_FAIL; } if (1 > EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pub_exp)){ BN_free(pub_exp); return SOTER_FAIL; } /* Override default key size for RSA key. Currently OpenSSL has default key size of 1024. LibreSSL has 2048. We will put 2048 explicitly */ if (1 > EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, SOTER_RSA_KEY_LENGTH, NULL)){ return SOTER_FAIL; } if(!EVP_PKEY_keygen(pkey_ctx, &pkey)){ return SOTER_FAIL; } return SOTER_SUCCESS; /* end of copy-paste from /src/soter/openssl/soter_asym_cipher.c*/ }
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, unsigned char *key, int keylen) { EVP_PKEY_CTX *mac_ctx = NULL; EVP_PKEY *mac_key = NULL; mac_ctx = EVP_PKEY_CTX_new_id(type, e); if (!mac_ctx) return NULL; if (EVP_PKEY_keygen_init(mac_ctx) <= 0) goto merr; if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0) goto merr; if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) goto merr; merr: if (mac_ctx) EVP_PKEY_CTX_free(mac_ctx); return mac_key; }
void ecdhe_context::generate_keys() { evp_pkey_context_type parameters_context(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)); error::throw_error_if_not(parameters_context.get()); error::throw_error_if(EVP_PKEY_paramgen_init(parameters_context.get()) != 1); error::throw_error_if(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(parameters_context.get(), m_nid) != 1); EVP_PKEY* cparameters = nullptr; error::throw_error_if_not(EVP_PKEY_paramgen(parameters_context.get(), &cparameters) == 1); pkey parameters = pkey::take_ownership(cparameters); evp_pkey_context_type key_generation_context(EVP_PKEY_CTX_new(parameters.raw(), NULL)); error::throw_error_if_not(key_generation_context.get()); error::throw_error_if(EVP_PKEY_keygen_init(key_generation_context.get()) != 1); EVP_PKEY* private_key = nullptr; error::throw_error_if(EVP_PKEY_keygen(key_generation_context.get(), &private_key) != 1); m_private_key = pkey::take_ownership(private_key); }
static int autoca_genpkey(int bits, EVP_PKEY **pkey) { EVP_PKEY_CTX *kctx; int rc; kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); if (kctx == NULL) return -1; if (EVP_PKEY_keygen_init(kctx) <= 0) { EVP_PKEY_CTX_free(kctx); return -1; } if (EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, bits) <= 0) { EVP_PKEY_CTX_free(kctx); return -1; } rc = EVP_PKEY_keygen(kctx, pkey); EVP_PKEY_CTX_free(kctx); return rc; }
soter_status_t soter_rsa_key_pair_gen_init(soter_rsa_key_pair_gen_t* ctx, const unsigned key_length){ EVP_PKEY *pkey; pkey = EVP_PKEY_new(); SOTER_CHECK(pkey); /* Only RSA supports asymmetric encryption */ SOTER_IF_FAIL(EVP_PKEY_set_type(pkey, EVP_PKEY_RSA), EVP_PKEY_free(pkey)); ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); SOTER_IF_FAIL(ctx->pkey_ctx,EVP_PKEY_free(pkey)); BIGNUM *pub_exp; SOTER_IF_FAIL(EVP_PKEY_keygen_init(ctx->pkey_ctx), EVP_PKEY_CTX_free(ctx->pkey_ctx)); /* Although it seems that OpenSSL/LibreSSL use 0x10001 as default public exponent, we will set it explicitly just in case */ pub_exp = BN_new(); SOTER_CHECK(pub_exp); SOTER_IF_FAIL(BN_set_word(pub_exp, RSA_F4), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); SOTER_IF_FAIL(1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pub_exp), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); /* Override default key size for RSA key. Currently OpenSSL has default key size of 1024. LibreSSL has 2048. We will put 2048 explicitly */ SOTER_IF_FAIL((1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, rsa_key_length(key_length), NULL)), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); SOTER_IF_FAIL(EVP_PKEY_keygen(ctx->pkey_ctx, &pkey), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); return SOTER_SUCCESS; }
int main() { EVP_PKEY_CTX *pctx, *kctx; EVP_PKEY_CTX *ctx; unsigned char *secret; EVP_PKEY *pkey = NULL, *peerkey, *params = NULL; /* NB: assumes pkey, peerkey have been already set up */ /* Create the context for parameter generation */ if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) handleErrors(); /* Initialise the parameter generation */ if(1 != EVP_PKEY_paramgen_init(pctx)) handleErrors(); /* We're going to use the ANSI X9.62 Prime 256v1 curve */ if(1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1)) handleErrors(); /* Create the parameter object params */ if (!EVP_PKEY_paramgen(pctx, ¶ms)) handleErrors(); /* Create the context for the key generation */ if(NULL == (kctx = EVP_PKEY_CTX_new(params, NULL))) handleErrors(); /* Generate the key */ if(1 != EVP_PKEY_keygen_init(kctx)) handleErrors(); if (1 != EVP_PKEY_keygen(kctx, &pkey)) handleErrors(); /* Get the peer's public key, and provide the peer with our public key - * how this is done will be specific to your circumstances */ peerkey = get_peerkey(pkey); /* Create the context for the shared secret derivation */ if(NULL == (ctx = EVP_PKEY_CTX_new(pkey, NULL))) handleErrors(); /* Initialise */ if(1 != EVP_PKEY_derive_init(ctx)) handleErrors(); /* Provide the peer public key */ if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey)) handleErrors(); /* Determine buffer length for shared secret */ if(1 != EVP_PKEY_derive(ctx, NULL, secret_len)) handleErrors(); /* Create the buffer */ if(NULL == (secret = OPENSSL_malloc(*secret_len))) handleErrors(); /* Derive the shared secret */ if(1 != (EVP_PKEY_derive(ctx, secret, secret_len))) handleErrors(); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(peerkey); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(kctx); EVP_PKEY_free(params); EVP_PKEY_CTX_free(pctx); /* Never use a derived secret directly. Typically it is passed * through some hash function to produce a key */ return 0; }
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 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; }
// Key factory bool OSSLGOST::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */) { // Check parameters if ((ppKeyPair == NULL) || (parameters == NULL)) { return false; } if (!parameters->areOfType(ECParameters::type)) { ERROR_MSG("Invalid parameters supplied for GOST key generation"); return false; } ECParameters* params = (ECParameters*) parameters; ByteString paramA = "06072a850302022301"; if (params->getEC() != paramA) { ERROR_MSG("unsupported parameters"); return false; } // Generate the key-pair EVP_PKEY_CTX* ctx = NULL; EVP_PKEY* pkey = NULL; OSSLGOSTKeyPair* kp; ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) { ERROR_MSG("EVP_PKEY_CTX_new_id failed"); goto err; } if (EVP_PKEY_keygen_init(ctx) <= 0) { ERROR_MSG("EVP_PKEY_keygen_init failed"); goto err; } if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) { ERROR_MSG("EVP_PKEY_CTX_ctrl_str failed"); goto err; } if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { ERROR_MSG("EVP_PKEY_keygen failed"); goto err; } EVP_PKEY_CTX_free(ctx); ctx = NULL; // Create an asymmetric key-pair object to return kp = new OSSLGOSTKeyPair(); ((OSSLGOSTPublicKey*) kp->getPublicKey())->setFromOSSL(pkey); ((OSSLGOSTPrivateKey*) kp->getPrivateKey())->setFromOSSL(pkey); *ppKeyPair = kp; // Release the key EVP_PKEY_free(pkey); return true; err: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); if (pkey != NULL) EVP_PKEY_free(pkey); return false; }
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */ DH *dh_params = NULL; int mpint; /* 0 or 4 */ { ERL_NIF_TERM head, tail; BIGNUM *dh_p = NULL, *dh_g = NULL, *priv_key_in = NULL; unsigned long len = 0; if (!(get_bn_from_bin(env, argv[0], &priv_key_in) || argv[0] == atom_undefined) || !enif_get_list_cell(env, argv[1], &head, &tail) || !get_bn_from_bin(env, head, &dh_p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dh_g) || !enif_is_empty_list(env, tail) || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4) || !enif_get_ulong(env, argv[3], &len) /* Load dh_params with values to use by the generator. Mem mgmnt transfered from dh_p etc to dh_params */ || !(dh_params = DH_new()) || (priv_key_in && !DH_set0_key(dh_params, NULL, priv_key_in)) || !DH_set0_pqg(dh_params, dh_p, NULL, dh_g) ) { if (priv_key_in) BN_free(priv_key_in); if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (dh_params) DH_free(dh_params); return enif_make_badarg(env); } if (len) { if (len < BN_num_bits(dh_p)) DH_set_length(dh_params, len); else { if (priv_key_in) BN_free(priv_key_in); if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (dh_params) DH_free(dh_params); return enif_make_badarg(env); } } } #ifdef HAS_EVP_PKEY_CTX { EVP_PKEY_CTX *ctx; EVP_PKEY *dhkey, *params; int success; params = EVP_PKEY_new(); success = EVP_PKEY_set1_DH(params, dh_params); /* set the key referenced by params to dh_params... */ DH_free(dh_params); /* ...dh_params (and params) must be freed */ if (!success) return atom_error; ctx = EVP_PKEY_CTX_new(params, NULL); EVP_PKEY_free(params); if (!ctx) { return atom_error; } if (!EVP_PKEY_keygen_init(ctx)) { /* EVP_PKEY_CTX_free(ctx); */ return atom_error; } dhkey = EVP_PKEY_new(); if (!EVP_PKEY_keygen(ctx, &dhkey)) { /* "performs a key generation operation, the ... */ /*... generated key is written to ppkey." (=last arg) */ /* EVP_PKEY_CTX_free(ctx); */ /* EVP_PKEY_free(dhkey); */ return atom_error; } dh_params = EVP_PKEY_get1_DH(dhkey); /* return the referenced key. dh_params and dhkey must be freed */ EVP_PKEY_free(dhkey); if (!dh_params) { /* EVP_PKEY_CTX_free(ctx); */ return atom_error; } EVP_PKEY_CTX_free(ctx); } #else if (!DH_generate_key(dh_params)) return atom_error; #endif { unsigned char *pub_ptr, *prv_ptr; int pub_len, prv_len; ERL_NIF_TERM ret_pub, ret_prv; const BIGNUM *pub_key_gen, *priv_key_gen; DH_get0_key(dh_params, &pub_key_gen, &priv_key_gen); /* Get pub_key_gen and priv_key_gen. "The values point to the internal representation of the public key and private key values. This memory should not be freed directly." says man */ pub_len = BN_num_bytes(pub_key_gen); prv_len = BN_num_bytes(priv_key_gen); pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub); prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv); if (mpint) { put_int32(pub_ptr, pub_len); pub_ptr += 4; put_int32(prv_ptr, prv_len); prv_ptr += 4; } BN_bn2bin(pub_key_gen, pub_ptr); BN_bn2bin(priv_key_gen, prv_ptr); ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len); ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len); DH_free(dh_params); return enif_make_tuple2(env, ret_pub, ret_prv); } }