void kexdh_client(Kex *kex) { BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; DH *dh; Key *server_host_key; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf, *hash; u_int klen, slen, sbloblen, hashlen; int kout; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: dh = dh_new_group14(); break; default: fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); } dh_gen_key(dh, kex->we_need * 8); packet_start(SSH2_MSG_KEXDH_INIT); packet_put_bignum2(dh->pub_key); packet_send(); debug("sending SSH2_MSG_KEXDH_INIT"); #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, dh->pub_key); fprintf(stderr, "\n"); #endif debug("expecting SSH2_MSG_KEXDH_REPLY"); packet_read_expect(SSH2_MSG_KEXDH_REPLY); /* key, cert */ server_host_key_blob = packet_get_string(&sbloblen); server_host_key = key_from_blob(server_host_key_blob, sbloblen); if (server_host_key == NULL) fatal("cannot decode server_host_key_blob"); if (server_host_key->type != kex->hostkey_type) fatal("type mismatch for decoded server_host_key_blob"); if (kex->verify_host_key == NULL) fatal("cannot verify server_host_key"); if (kex->verify_host_key(server_host_key) == -1) fatal("server_host_key verification failed"); /* DH parameter f, server public DH key */ if ((dh_server_pub = BN_new()) == NULL) fatal("dh_server_pub == NULL"); packet_get_bignum2(dh_server_pub); #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif /* signed H */ signature = packet_get_string(&slen); packet_check_eom(); if (!dh_pub_is_valid(dh, dh_server_pub)) packet_disconnect("bad server public DH value"); klen = DH_size(dh); kbuf = xmalloc(klen); if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((shared_secret = BN_new()) == NULL) fatal("kexdh_client: BN_new failed"); if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) fatal("kexdh_client: BN_bin2bn failed"); memset(kbuf, 0, klen); free(kbuf); /* calc and verify H */ kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, dh->pub_key, dh_server_pub, shared_secret, &hash, &hashlen ); free(server_host_key_blob); BN_clear_free(dh_server_pub); DH_free(dh); if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); free(signature); /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); }
static int mech_step(sasl_session_t *p, char *message, size_t len, char **out, size_t *out_len) { DH *dh = NULL; AES_KEY key; BIGNUM *their_key = NULL; myuser_t *mu; char *secret = NULL, *userpw = NULL, *ptr = NULL; char iv[AES_BLOCK_SIZE]; int ret = ASASL_FAIL; uint16_t size; int secret_size; if (!p->mechdata) return ASASL_FAIL; dh = (DH*)p->mechdata; /* Their pub_key */ if (len <= 2) goto end; size = ntohs(*(uint16_t *)message); message += 2; len -= 2; if (size >= len) goto end; if ((their_key = BN_bin2bn(message, size, NULL)) == NULL) goto end; message += size; len -= size; /* Data must be a multiple of the AES block size. (16) * Verify we also have an IV and at least one block of data. * Cap at a rather arbitrary limit of 272 (IV + 16 blocks of 16 each). */ if (len < sizeof(iv) + AES_BLOCK_SIZE || len % AES_BLOCK_SIZE || len > 272) goto end; /* Extract the IV */ memcpy(iv, message, sizeof(iv)); message += sizeof(iv); len -= sizeof(iv); /* Compute shared secret */ secret = malloc(DH_size(dh)); secret_size = DH_compute_key(secret, their_key, dh); if (secret_size <= 0) goto end; /* Decrypt! (AES_set_decrypt_key takes bits not bytes, hence multiply * by 8) */ AES_set_decrypt_key(secret, secret_size * 8, &key); ptr = userpw = malloc(len + 1); userpw[len] = '\0'; AES_cbc_encrypt(message, userpw, len, &key, iv, AES_DECRYPT); /* Username */ size = strlen(ptr); if (size++ >= NICKLEN) /* our base64 routines null-terminate - how polite */ goto end; p->username = strdup(ptr); ptr += size; len -= size; if ((mu = myuser_find_by_nick(p->username)) == NULL) goto end; /* Password remains */ if (verify_password(mu, ptr)) ret = ASASL_DONE; end: if (their_key) BN_free(their_key); free(secret); free(userpw); return ret; }
/* signing */ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *res; int i, num = 0, r = -1; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); break; case RSA_X931_PADDING: i = RSA_padding_add_X931(buf, num, from, flen); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf, num, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || (rsa->version == RSA_ASN1_VERSION_MULTI) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) { if (!BN_sub(f, rsa->n, ret)) goto err; if (BN_cmp(ret, f) > 0) res = f; else res = ret; } else { res = ret; } /* * BN_bn2binpad puts in leading 0 bytes if the number is less than * the length of the modulus. */ r = BN_bn2binpad(res, to, num); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return r; }
int StealthSecretSpend(ec_secret& scanSecret, ec_point& ephemPubkey, ec_secret& spendSecret, ec_secret& secretOut) { /* c = H(dP) R' = R + cG [without decrypting wallet] = (f + c)G [after decryption of wallet] Remember: mod curve.order, pad with 0x00s where necessary? */ int rv = 0; std::vector<uint8_t> vchOutP; BN_CTX* bnCtx = NULL; BIGNUM* bnScanSecret = NULL; BIGNUM* bnP = NULL; EC_POINT* P = NULL; BIGNUM* bnOutP = NULL; BIGNUM* bnc = NULL; BIGNUM* bnOrder = NULL; BIGNUM* bnSpend = NULL; EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); if (!ecgrp) { printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n"); return 1; }; if (!(bnCtx = BN_CTX_new())) { printf("StealthSecretSpend(): BN_CTX_new failed.\n"); rv = 1; goto End; }; if (!(bnScanSecret = BN_bin2bn(&scanSecret.e[0], ec_secret_size, BN_new()))) { printf("StealthSecretSpend(): bnScanSecret BN_bin2bn failed.\n"); rv = 1; goto End; }; if (!(bnP = BN_bin2bn(&ephemPubkey[0], ephemPubkey.size(), BN_new()))) { printf("StealthSecretSpend(): bnP BN_bin2bn failed\n"); rv = 1; goto End; }; if (!(P = EC_POINT_bn2point(ecgrp, bnP, NULL, bnCtx))) { printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n"); rv = 1; goto End; }; // -- dP if (!EC_POINT_mul(ecgrp, P, NULL, P, bnScanSecret, bnCtx)) { printf("StealthSecretSpend(): dP EC_POINT_mul failed\n"); rv = 1; goto End; }; if (!(bnOutP = EC_POINT_point2bn(ecgrp, P, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx))) { printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n"); rv = 1; goto End; }; vchOutP.resize(ec_compressed_size); if (BN_num_bytes(bnOutP) != (int) ec_compressed_size || BN_bn2bin(bnOutP, &vchOutP[0]) != (int) ec_compressed_size) { printf("StealthSecretSpend(): bnOutP incorrect length.\n"); rv = 1; goto End; }; uint8_t hash1[32]; SHA256(&vchOutP[0], vchOutP.size(), (uint8_t*)hash1); if (!(bnc = BN_bin2bn(&hash1[0], 32, BN_new()))) { printf("StealthSecretSpend(): BN_bin2bn failed\n"); rv = 1; goto End; }; if (!(bnOrder = BN_new()) || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx)) { printf("StealthSecretSpend(): EC_GROUP_get_order failed\n"); rv = 1; goto End; }; if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new()))) { printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n"); rv = 1; goto End; }; //if (!BN_add(r, a, b)) return 0; //return BN_nnmod(r, r, m, ctx); if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx)) { printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n"); rv = 1; goto End; }; if (BN_is_zero(bnSpend)) // possible? { printf("StealthSecretSpend(): bnSpend is zero.\n"); rv = 1; goto End; }; if (BN_num_bytes(bnSpend) != (int) ec_secret_size || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size) { printf("StealthSecretSpend(): bnSpend incorrect length.\n"); rv = 1; goto End; }; End: if (bnSpend) BN_free(bnSpend); if (bnOrder) BN_free(bnOrder); if (bnc) BN_free(bnc); if (bnOutP) BN_free(bnOutP); if (P) EC_POINT_free(P); if (bnP) BN_free(bnP); if (bnScanSecret) BN_free(bnScanSecret); if (bnCtx) BN_CTX_free(bnCtx); EC_GROUP_free(ecgrp); return rv; };
static isc_result_t opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; RSA *rsa = NULL, *pubrsa = NULL; #ifdef USE_ENGINE ENGINE *e = NULL; #endif isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; #if defined(USE_ENGINE) || USE_EVP EVP_PKEY *pkey = NULL; #endif #if USE_EVP if (pub != NULL && pub->keydata.pkey != NULL) pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); #else if (pub != NULL && pub->keydata.rsa != NULL) { pubrsa = pub->keydata.rsa; pub->keydata.rsa = NULL; } #endif /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_RSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } /* * Is this key is stored in a HSM? * See if we can fetch it. */ if (label != NULL) { #ifdef USE_ENGINE if (engine == NULL) DST_RET(DST_R_NOENGINE); e = dst__openssl_getengine(engine); if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) { /* ERR_print_errors_fp(stderr); */ DST_RET(ISC_R_NOTFOUND); } key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); #else DST_RET(DST_R_NOENGINE); #endif } rsa = RSA_new(); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); SET_FLAGS(rsa); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EVP_PKEY_set1_RSA(pkey, rsa)) DST_RET(ISC_R_FAILURE); key->keydata.pkey = pkey; #else key->keydata.rsa = rsa; #endif for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: continue; case TAG_RSA_LABEL: continue; case TAG_RSA_PIN: continue; default: bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); } switch (priv.elements[i].tag) { case TAG_RSA_MODULUS: rsa->n = bn; break; case TAG_RSA_PUBLICEXPONENT: rsa->e = bn; break; case TAG_RSA_PRIVATEEXPONENT: rsa->d = bn; break; case TAG_RSA_PRIME1: rsa->p = bn; break; case TAG_RSA_PRIME2: rsa->q = bn; break; case TAG_RSA_EXPONENT1: rsa->dmp1 = bn; break; case TAG_RSA_EXPONENT2: rsa->dmq1 = bn; break; case TAG_RSA_COEFFICIENT: rsa->iqmp = bn; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); #if USE_EVP RSA_free(rsa); #endif return (ISC_R_SUCCESS); err: #if USE_EVP if (pkey != NULL) EVP_PKEY_free(pkey); #endif if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); opensslrsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }
static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; /* Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if(!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } /* This check was for equality but PGP does evil things * and chops off the top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from,(int)flen,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = NULL, *local_d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_d = d = BN_new(); if(!d) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { if(local_d) BN_free(local_d); goto err; } if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) { if(local_d) BN_free(local_d); goto err; } if(local_d) BN_free(local_d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p=buf; j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); break; #ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); break; #endif case RSA_SSLV23_PADDING: r=RSA_padding_check_SSLv23(to,num,buf,j,num); break; case RSA_NO_PADDING: r=RSA_padding_check_none(to,num,buf,j,num); break; default: RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
static int mech_step(sasl_session_t *p, char *message, int len, char **out, int *out_len) { DH *dh = NULL; BF_KEY key; BIGNUM *their_key = NULL; myuser_t *mu; char *ptr, *secret = NULL, *password = NULL; int size, ret = ASASL_FAIL; if (!p->mechdata) return ASASL_FAIL; dh = (DH*)p->mechdata; /* Their pub_key */ if (len < 2) goto end; size = ntohs(*(unsigned int*)message); message += 2; len -= 2; if (size > len) goto end; if ((their_key = BN_bin2bn((unsigned char *)message, size, NULL)) == NULL) goto end; message += size; len -= size; /* Username */ size = strlen(message); if (size >= NICKLEN) /* our base64 routines null-terminate - how polite */ goto end; p->username = strdup(message); message += size + 1; len -= size + 1; if ((mu = myuser_find_by_nick(p->username)) == NULL) goto end; /* AES-encrypted password remains */ /* Compute shared secret */ secret = (char*)malloc(DH_size(dh)); if ((size = DH_compute_key((unsigned char *)secret, their_key, dh)) == -1) goto end; /* Data must be multiple of block size, and let's be reasonable about size */ if (len == 0 || len % 8 || len > 128) goto end; /* Decrypt! */ BF_set_key(&key, size, (unsigned char *)secret); ptr = password = (char*)malloc(len + 1); password[len] = '\0'; while (len) { BF_ecb_encrypt((unsigned char *)message, (unsigned char *)ptr, &key, BF_DECRYPT); message += 8; ptr += 8; len -= 8; } if (verify_password(mu, password)) ret = ASASL_DONE; end: if (their_key) BN_free(their_key); free(secret); free(password); return ret; }
int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { const unsigned rsa_size = RSA_size(rsa); BIGNUM *f, *result; int ret = 0; int r = -1; uint8_t *buf = NULL; BN_CTX *ctx = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); return 0; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS && BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (padding == RSA_NO_PADDING) { buf = out; } else { /* Allocate a temporary buffer to hold the padded plaintext. */ buf = OPENSSL_malloc(rsa_size); if (buf == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } } if (!f || !result) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (in_len != rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); goto err; } if (BN_bin2bn(in, in_len, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) { goto err; } if (!BN_bn2bin_padded(buf, rsa_size, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size); break; case RSA_NO_PADDING: r = rsa_size; break; default: OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); } else { *out_len = r; ret = 1; } err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (padding != RSA_NO_PADDING && buf != NULL) { OPENSSL_cleanse(buf, rsa_size); OPENSSL_free(buf); } return ret; }
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { BIGNUM *f, *result; BN_CTX *ctx = NULL; unsigned blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (BN_bin2bn(in, len, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { /* Usually the padding functions would catch this. */ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_blinding_get(rsa, &blinding_index, ctx); if (blinding == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) { goto err; } } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->mod_exp(result, f, rsa, ctx)) { goto err; } } else { BIGNUM local_d; BIGNUM *d = NULL; BN_init(&local_d); d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->mont_n)) { goto err; } } if (blinding) { if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) { goto err; } } if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } ret = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (blinding != NULL) { rsa_blinding_release(rsa, blinding, blinding_index); } return ret; }
int RSA_set_RSAPRIVATEKEYBLOB(RSA *rsa, const RSAPRIVATEKEYBLOB *blob) { int ret = 0; BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; BIGNUM *p = NULL; BIGNUM *q = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; BIGNUM *iqmp = NULL; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (blob->AlgID != SGD_RSA) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_ALGOR); return 0; } if (blob->BitLen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS || blob->BitLen > sizeof(blob->Modulus) * 8 || blob->BitLen % 8 != 0 || blob->BitLen % 16 != 0) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!(n = BN_bin2bn(blob->Modulus, sizeof(blob->Modulus), NULL)) || !(e = BN_bin2bn(blob->PublicExponent, sizeof(blob->PublicExponent), NULL)) || !(d = BN_bin2bn(blob->PrivateExponent, sizeof(blob->PrivateExponent), NULL)) || !(p = BN_bin2bn(blob->Prime1, sizeof(blob->Prime1), NULL)) || !(q = BN_bin2bn(blob->Prime2, sizeof(blob->Prime2), NULL)) || !(dmp1 = BN_bin2bn(blob->Prime1Exponent, sizeof(blob->Prime1Exponent), NULL)) || !(dmq1 = BN_bin2bn(blob->Prime2Exponent, sizeof(blob->Prime2Exponent), NULL)) || !(iqmp = BN_bin2bn(blob->Coefficient, sizeof(blob->Coefficient), NULL))) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_BN_LIB); goto end; } if (!RSA_set0_key(rsa, n, e, d)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } n = NULL; e = NULL; d = NULL; if (!RSA_set0_factors(rsa, p, q)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } p = NULL; q = NULL; if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } dmp1 = NULL; dmq1 = NULL; iqmp = NULL; ret = 1; end: BN_free(n); BN_free(e); BN_free(d); BN_free(p); BN_free(q); BN_free(dmp1); BN_free(dmq1); BN_free(iqmp); return ret; }
/* * These parameters are from test/recipes/04-test_pem_data/dsaparam.pem, * converted using dsaparam -C */ static DSA *load_dsa_params(void) { static unsigned char dsap_2048[] = { 0xAE, 0x35, 0x7D, 0x4E, 0x1D, 0x96, 0xE2, 0x9F, 0x00, 0x96, 0x60, 0x5A, 0x6E, 0x4D, 0x07, 0x8D, 0xA5, 0x7C, 0xBC, 0xF9, 0xAD, 0xD7, 0x9F, 0xD5, 0xE9, 0xEE, 0xA6, 0x33, 0x51, 0xDE, 0x7B, 0x72, 0xD2, 0x75, 0xAA, 0x71, 0x77, 0xF1, 0x63, 0xFB, 0xB6, 0xEC, 0x5A, 0xBA, 0x0D, 0x72, 0xA2, 0x1A, 0x1C, 0x64, 0xB8, 0xE5, 0x89, 0x09, 0x6D, 0xC9, 0x6F, 0x0B, 0x7F, 0xD2, 0xCE, 0x9F, 0xEF, 0x87, 0x5A, 0xB6, 0x67, 0x2F, 0xEF, 0xEE, 0xEB, 0x59, 0xF5, 0x5E, 0xFF, 0xA8, 0x28, 0x84, 0x9E, 0x5B, 0x37, 0x09, 0x11, 0x80, 0x7C, 0x08, 0x5C, 0xD5, 0xE1, 0x48, 0x4B, 0xD2, 0x68, 0xFB, 0x3F, 0x9F, 0x2B, 0x6B, 0x6C, 0x0D, 0x48, 0x1B, 0x1A, 0x80, 0xC2, 0xEB, 0x11, 0x1B, 0x37, 0x79, 0xD6, 0x8C, 0x8B, 0x72, 0x3E, 0x67, 0xA5, 0x05, 0x0E, 0x41, 0x8A, 0x9E, 0x35, 0x50, 0xB4, 0xD2, 0x40, 0x27, 0x6B, 0xFD, 0xE0, 0x64, 0x6B, 0x5B, 0x38, 0x42, 0x94, 0xB5, 0x49, 0xDA, 0xEF, 0x6E, 0x78, 0x37, 0xCD, 0x30, 0x89, 0xC3, 0x45, 0x50, 0x7B, 0x9C, 0x8C, 0xE7, 0x1C, 0x98, 0x70, 0x71, 0x5D, 0x79, 0x5F, 0xEF, 0xE8, 0x94, 0x85, 0x53, 0x3E, 0xEF, 0xA3, 0x2C, 0xCE, 0x1A, 0xAB, 0x7D, 0xD6, 0x5E, 0x14, 0xCD, 0x51, 0x54, 0x89, 0x9D, 0x77, 0xE4, 0xF8, 0x22, 0xF0, 0x35, 0x10, 0x75, 0x05, 0x71, 0x51, 0x4F, 0x8C, 0x4C, 0x5C, 0x0D, 0x2C, 0x2C, 0xBE, 0x6C, 0x34, 0xEE, 0x12, 0x82, 0x87, 0x03, 0x19, 0x06, 0x12, 0xA8, 0xAA, 0xF4, 0x0D, 0x3C, 0x49, 0xCC, 0x70, 0x5A, 0xD8, 0x32, 0xEE, 0x32, 0x50, 0x85, 0x70, 0xE8, 0x18, 0xFD, 0x74, 0x80, 0x53, 0x32, 0x57, 0xEE, 0x50, 0xC9, 0xAE, 0xEB, 0xAE, 0xB6, 0x22, 0x32, 0x16, 0x6B, 0x8C, 0x59, 0xDA, 0xEE, 0x1D, 0x33, 0xDF, 0x4C, 0xA2, 0x3D }; static unsigned char dsaq_2048[] = { 0xAD, 0x2D, 0x6E, 0x17, 0xB0, 0xF3, 0xEB, 0xC7, 0xB8, 0xEE, 0x95, 0x78, 0xF2, 0x17, 0xF5, 0x33, 0x01, 0x67, 0xBC, 0xDE, 0x93, 0xFF, 0xEE, 0x40, 0xE8, 0x7F, 0xF1, 0x93, 0x6D, 0x4B, 0x87, 0x13 }; static unsigned char dsag_2048[] = { 0x66, 0x6F, 0xDA, 0x63, 0xA5, 0x8E, 0xD2, 0x4C, 0xD5, 0x45, 0x2D, 0x76, 0x5D, 0x5F, 0xCD, 0x4A, 0xB4, 0x1A, 0x42, 0x35, 0x86, 0x3A, 0x6F, 0xA9, 0xFA, 0x27, 0xAB, 0xDE, 0x03, 0x21, 0x36, 0x0A, 0x07, 0x29, 0xC9, 0x2F, 0x6D, 0x49, 0xA8, 0xF7, 0xC6, 0xF4, 0x92, 0xD7, 0x73, 0xC1, 0xD8, 0x76, 0x0E, 0x61, 0xA7, 0x0B, 0x6E, 0x96, 0xB8, 0xC8, 0xCB, 0x38, 0x35, 0x12, 0x20, 0x79, 0xA5, 0x08, 0x28, 0x35, 0x5C, 0xBC, 0x52, 0x16, 0xAF, 0x52, 0xBA, 0x0F, 0xC3, 0xB1, 0x63, 0x12, 0x27, 0x0B, 0x74, 0xA4, 0x47, 0x43, 0xD6, 0x30, 0xB8, 0x9C, 0x2E, 0x40, 0x14, 0xCD, 0x99, 0x7F, 0xE8, 0x8E, 0x37, 0xB0, 0xA9, 0x3F, 0x54, 0xE9, 0x66, 0x22, 0x61, 0x4C, 0xF8, 0x49, 0x03, 0x57, 0x14, 0x32, 0x1D, 0x37, 0x3D, 0xE2, 0x92, 0xF8, 0x8E, 0xA0, 0x6A, 0x66, 0x63, 0xF0, 0xB0, 0x6E, 0x07, 0x2B, 0x3D, 0xBF, 0xD0, 0x84, 0x6A, 0xAA, 0x1F, 0x30, 0x77, 0x65, 0xE5, 0xFC, 0xF5, 0xEC, 0x55, 0xCE, 0x73, 0xDB, 0xBE, 0xA7, 0x8D, 0x3A, 0x9F, 0x7A, 0xED, 0x4F, 0xAF, 0xA2, 0x80, 0x4C, 0x30, 0x9E, 0x28, 0x49, 0x65, 0x40, 0xF0, 0x03, 0x45, 0x56, 0x99, 0xA2, 0x93, 0x1B, 0x9C, 0x46, 0xDE, 0xBD, 0xA8, 0xAB, 0x5F, 0x90, 0x3F, 0xB7, 0x3F, 0xD4, 0x6F, 0x8D, 0x5A, 0x30, 0xE1, 0xD4, 0x63, 0x3A, 0x6A, 0x7C, 0x8F, 0x24, 0xFC, 0xD9, 0x14, 0x28, 0x09, 0xE4, 0x84, 0x4E, 0x17, 0x43, 0x56, 0xB8, 0xD4, 0x4B, 0xA2, 0x29, 0x45, 0xD3, 0x13, 0xF0, 0xC2, 0x76, 0x9B, 0x01, 0xA0, 0x80, 0x6E, 0x93, 0x63, 0x5E, 0x87, 0x24, 0x20, 0x2A, 0xFF, 0xBB, 0x9F, 0xA8, 0x99, 0x6C, 0xA7, 0x9A, 0x00, 0xB9, 0x7D, 0xDA, 0x66, 0xC9, 0xC0, 0x72, 0x72, 0x22, 0x0F, 0x1A, 0xCC, 0x23, 0xD9, 0xB7, 0x5F, 0x1B }; DSA *dsa = DSA_new(); BIGNUM *p, *q, *g; if (dsa == NULL) return NULL; if (!DSA_set0_pqg(dsa, p = BN_bin2bn(dsap_2048, sizeof(dsap_2048), NULL), q = BN_bin2bn(dsaq_2048, sizeof(dsaq_2048), NULL), g = BN_bin2bn(dsag_2048, sizeof(dsag_2048), NULL))) { DSA_free(dsa); BN_free(p); BN_free(q); BN_free(g); return NULL; } return dsa; }
static int run_rfc5114_tests(void) { int i; DH *dhA = NULL, *dhB = NULL; unsigned char *Z1 = NULL, *Z2 = NULL; for (i = 0; i < (int)(sizeof(rfctd) / sizeof(rfc5114_td)); i++) { const rfc5114_td *td = rfctd + i; /* Set up DH structures setting key components */ dhA = td->get_param(NULL); dhB = td->get_param(NULL); if (!dhA || !dhB) { goto bad_err; } dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, NULL); dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, NULL); dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, NULL); dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, NULL); if (!dhA->priv_key || !dhA->pub_key || !dhB->priv_key || !dhB->pub_key) { goto bad_err; } if ((td->Z_len != (size_t)DH_size(dhA)) || (td->Z_len != (size_t)DH_size(dhB))) { goto err; } Z1 = OPENSSL_malloc(DH_size(dhA)); Z2 = OPENSSL_malloc(DH_size(dhB)); /* Work out shared secrets using both sides and compare * with expected values. */ if (!DH_compute_key(Z1, dhB->pub_key, dhA) || !DH_compute_key(Z2, dhA->pub_key, dhB)) { goto bad_err; } if (memcmp(Z1, td->Z, td->Z_len) || memcmp(Z2, td->Z, td->Z_len)) { goto err; } printf("RFC5114 parameter test %d OK\n", i + 1); DH_free(dhA); dhA = NULL; DH_free(dhB); dhB = NULL; OPENSSL_free(Z1); Z1 = NULL; OPENSSL_free(Z2); Z2 = NULL; } printf("PASS\n"); return 1; bad_err: fprintf(stderr, "Initalisation error RFC5114 set %d\n", i + 1); ERR_print_errors_fp(stderr); err: if (Z1 != NULL) { OPENSSL_free(Z1); } if (Z2 != NULL) { OPENSSL_free(Z2); } if (dhA != NULL) { DH_free(dhA); } if (dhB != NULL) { DH_free(dhB); } fprintf(stderr, "Test failed RFC5114 set %d\n", i + 1); return 0; }
int dnskey_build_pkey(struct rr_dnskey *rr) { if (rr->pkey_built) return rr->pkey ? 1 : 0; rr->pkey_built = 1; if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { RSA *rsa; EVP_PKEY *pkey; unsigned int e_bytes; unsigned char *pk; int l; rsa = RSA_new(); if (!rsa) goto done; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) /* public key is too short */ goto done; e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) /* public key is too short */ goto done; rsa->e = BN_bin2bn(pk, e_bytes, NULL); pk += e_bytes; l -= e_bytes; rsa->n = BN_bin2bn(pk, l, NULL); pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto done; rr->pkey = pkey; } else if (algorithm_type(rr->algorithm) == ALG_ECC_FAMILY) { EC_KEY *pubeckey; EVP_PKEY *pkey; unsigned char *pk; int l; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; if (rr->algorithm == ALG_ECDSAP256SHA256) { l = SHA256_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); } else if (rr->algorithm == ALG_ECDSAP384SHA384) { l = SHA384_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_secp384r1); } else { goto done; } if (!pubeckey) goto done; if (rr->pubkey.length != 2*l) { goto done; } pk = (unsigned char *)rr->pubkey.data; bn_x = BN_bin2bn(pk, l, NULL); bn_y = BN_bin2bn(&pk[l], l, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(pubeckey, bn_x, bn_y)) { goto done; } pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_assign_EC_KEY(pkey, pubeckey)) goto done; rr->pkey = pkey; } done: if (!rr->pkey) { moan(rr->rr.file_name, rr->rr.line, "error building pkey"); } return rr->pkey ? 1 : 0; }
static struct wpabuf * eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct wpabuf *resp = NULL; EC_POINT *K = NULL, *point = NULL; BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL; u16 offset; u8 *ptr, *scalar = NULL, *element = NULL; if (((data->private_value = BN_new()) == NULL) || ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) || ((cofactor = BN_new()) == NULL) || ((data->my_scalar = BN_new()) == NULL) || ((mask = BN_new()) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail"); goto fin; } if (!EC_GROUP_get_cofactor(data->grp->group, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor " "for curve"); goto fin; } BN_rand_range(data->private_value, data->grp->order); BN_rand_range(mask, data->grp->order); BN_add(data->my_scalar, data->private_value, mask); BN_mod(data->my_scalar, data->my_scalar, data->grp->order, data->bnctx); if (!EC_POINT_mul(data->grp->group, data->my_element, NULL, data->grp->pwe, mask, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): element allocation " "fail"); eap_pwd_state(data, FAILURE); goto fin; } if (!EC_POINT_invert(data->grp->group, data->my_element, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): element inversion fail"); goto fin; } BN_free(mask); if (((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): point allocation fail"); goto fin; } /* process the request */ if (((data->server_scalar = BN_new()) == NULL) || ((data->k = BN_new()) == NULL) || ((K = EC_POINT_new(data->grp->group)) == NULL) || ((point = EC_POINT_new(data->grp->group)) == NULL) || ((data->server_element = EC_POINT_new(data->grp->group)) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation " "fail"); goto fin; } /* element, x then y, followed by scalar */ ptr = (u8 *) payload; BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), x); ptr += BN_num_bytes(data->grp->prime); BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), y); ptr += BN_num_bytes(data->grp->prime); BN_bin2bn(ptr, BN_num_bytes(data->grp->order), data->server_scalar); if (!EC_POINT_set_affine_coordinates_GFp(data->grp->group, data->server_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element " "fail"); goto fin; } /* check to ensure server's element is not in a small sub-group */ if (BN_cmp(cofactor, BN_value_one())) { if (!EC_POINT_mul(data->grp->group, point, NULL, data->server_element, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " "server element by order!\n"); goto fin; } if (EC_POINT_is_at_infinity(data->grp->group, point)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): server element " "is at infinity!\n"); goto fin; } } /* compute the shared key, k */ if ((!EC_POINT_mul(data->grp->group, K, NULL, data->grp->pwe, data->server_scalar, data->bnctx)) || (!EC_POINT_add(data->grp->group, K, K, data->server_element, data->bnctx)) || (!EC_POINT_mul(data->grp->group, K, NULL, K, data->private_value, data->bnctx))) { wpa_printf(MSG_INFO, "EAP-PWD (peer): computing shared key " "fail"); goto fin; } /* ensure that the shared key isn't in a small sub-group */ if (BN_cmp(cofactor, BN_value_one())) { if (!EC_POINT_mul(data->grp->group, K, NULL, K, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " "shared key point by order"); goto fin; } } /* * This check is strictly speaking just for the case above where * co-factor > 1 but it was suggested that even though this is probably * never going to happen it is a simple and safe check "just to be * sure" so let's be safe. */ if (EC_POINT_is_at_infinity(data->grp->group, K)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): shared key point is at " "infinity!\n"); goto fin; } if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, K, data->k, NULL, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to extract " "shared secret from point"); goto fin; } /* now do the response */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->my_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): point assignment fail"); goto fin; } if (((scalar = os_malloc(BN_num_bytes(data->grp->order))) == NULL) || ((element = os_malloc(BN_num_bytes(data->grp->prime) * 2)) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): data allocation fail"); goto fin; } /* * bignums occupy as little memory as possible so one that is * sufficiently smaller than the prime or order might need pre-pending * with zeros. */ os_memset(scalar, 0, BN_num_bytes(data->grp->order)); os_memset(element, 0, BN_num_bytes(data->grp->prime) * 2); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->my_scalar); BN_bn2bin(data->my_scalar, scalar + offset); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, element + offset); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, sizeof(struct eap_pwd_hdr) + BN_num_bytes(data->grp->order) + (2 * BN_num_bytes(data->grp->prime)), EAP_CODE_RESPONSE, eap_get_id(reqData)); if (resp == NULL) goto fin; wpabuf_put_u8(resp, EAP_PWD_OPCODE_COMMIT_EXCH); /* we send the element as (x,y) follwed by the scalar */ wpabuf_put_data(resp, element, (2 * BN_num_bytes(data->grp->prime))); wpabuf_put_data(resp, scalar, BN_num_bytes(data->grp->order)); fin: os_free(scalar); os_free(element); BN_free(x); BN_free(y); BN_free(cofactor); EC_POINT_free(K); EC_POINT_free(point); if (resp == NULL) eap_pwd_state(data, FAILURE); else eap_pwd_state(data, PWD_Confirm_Req); return resp; }
static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f,*ret; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } } if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num=BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen); break; #ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0); break; #endif case RSA_SSLV23_PADDING: i=RSA_padding_add_SSLv23(buf,num,from,flen); break; case RSA_NO_PADDING: i=RSA_padding_add_none(buf,num,from,flen); break; default: RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf,num,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; /* put in leading 0 bytes if the number is less than the * length of the modulus */ j=BN_num_bytes(ret); i=BN_bn2bin(ret,&(to[num-j])); for (k=0; k<(num-i); k++) to[k]=0; r=num; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { const unsigned rsa_size = RSA_size(rsa); BIGNUM *f, *result; uint8_t *buf = NULL; BN_CTX *ctx = NULL; int i, ret = 0; if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); return 0; } if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS && BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); buf = OPENSSL_malloc(rsa_size); if (!f || !result || !buf) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); break; case RSA_PKCS1_OAEP_PADDING: /* Use the default parameters: SHA-1 for both hashes and no label. */ i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, NULL, 0, NULL, NULL); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, rsa_size, in, in_len); break; default: OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) { goto err; } if (BN_bin2bn(buf, rsa_size, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) { goto err; } /* put in leading 0 bytes if the number is less than the length of the * modulus */ if (!BN_bn2bin_padded(out, rsa_size, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } *out_len = rsa_size; ret = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf, rsa_size); OPENSSL_free(buf); } return ret; }
/* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *res; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; /* Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if(!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); break; case RSA_X931_PADDING: i=RSA_padding_add_X931(buf,num,from,flen); break; case RSA_NO_PADDING: i=RSA_padding_add_none(buf,num,from,flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf,num,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = NULL, *local_d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_d = d = BN_new(); if(!d) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d= rsa->d; if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { if(local_d) BN_free(local_d); goto err; } if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) { if(local_d) BN_free(local_d); goto err; } if(local_d) BN_free(local_d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) { BN_sub(f, rsa->n, ret); if (BN_cmp(ret, f) > 0) res = f; else res = ret; } else res = ret; /* put in leading 0 bytes if the number is less than the * length of the modulus */ j=BN_num_bytes(res); i=BN_bn2bin(res,&(to[num-j])); for (k=0; k<(num-i); k++) to[k]=0; r=num; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=0; unsigned char seed[SHA256_DIGEST_LENGTH]; unsigned char md[SHA256_DIGEST_LENGTH]; unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH]; BIGNUM *r0,*W,*X,*c,*test; BIGNUM *g=NULL,*q=NULL,*p=NULL; BN_MONT_CTX *mont=NULL; int i, k, n=0, m=0, qsize = qbits >> 3; int counter=0; int r=0; BN_CTX *ctx=NULL; unsigned int h=2; #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED); goto err; } if (FIPS_mode() && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW) && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL); goto err; } #endif if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) /* invalid q size */ return 0; if (evpmd == NULL) /* use SHA1 as default */ evpmd = EVP_sha1(); if (bits < 512) bits = 512; bits = (bits+63)/64*64; /* NB: seed_len == 0 is special case: copy generated seed to * seed_in if it is not NULL. */ if (seed_len && (seed_len < (size_t)qsize)) seed_in = NULL; /* seed buffer too small -- ignore */ if (seed_len > (size_t)qsize) seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits*/ if (seed_in != NULL) memcpy(seed, seed_in, seed_len); if ((ctx=BN_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test,BN_value_one(),bits-1)) goto err; for (;;) { for (;;) /* find q */ { int seed_is_random; /* step 1 */ if(!BN_GENCB_call(cb, 0, m++)) goto err; if (!seed_len) { if (RAND_pseudo_bytes(seed, qsize) < 0) goto err; seed_is_random = 1; } else { seed_is_random = 0; seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ } memcpy(buf , seed, qsize); memcpy(buf2, seed, qsize); /* precompute "SEED + 1" for step 7: */ for (i = qsize-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } /* step 2 */ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) goto err; if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) goto err; for (i = 0; i < qsize; i++) md[i]^=buf2[i]; /* step 3 */ md[0] |= 0x80; md[qsize-1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) goto err; /* step 4 */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) break; if (r != 0) goto err; /* do a callback call */ /* step 5 */ } if(!BN_GENCB_call(cb, 2, 0)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; /* step 6 */ counter=0; /* "offset = 2" */ n=(bits-1)/160; for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) goto err; /* step 7 */ BN_zero(W); /* now 'buf' contains "SEED + offset - 1" */ for (k=0; k<=n; k++) { /* obtain "SEED + offset + k" by incrementing: */ for (i = qsize-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL)) goto err; /* step 8 */ if (!BN_bin2bn(md, qsize, r0)) goto err; if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err; if (!BN_add(W,W,r0)) goto err; } /* more of step 8 */ if (!BN_mask_bits(W,bits-1)) goto err; if (!BN_copy(X,W)) goto err; if (!BN_add(X,X,test)) goto err; /* step 9 */ if (!BN_lshift1(r0,q)) goto err; if (!BN_mod(c,X,r0,ctx)) goto err; if (!BN_sub(r0,c,BN_value_one())) goto err; if (!BN_sub(p,X,r0)) goto err; /* step 10 */ if (BN_cmp(p,test) >= 0) { /* step 11 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ if (r != 0) goto err; } /* step 13 */ counter++; /* "offset = offset + n + 1" */ /* step 14 */ if (counter >= 4096) break; } } end: if(!BN_GENCB_call(cb, 2, 1)) goto err; /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; if (!BN_set_word(test,h)) goto err; if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; for (;;) { /* g=test^r0%p */ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test,test,BN_value_one())) goto err; h++; } if(!BN_GENCB_call(cb, 3, 1)) goto err; ok=1; err: if (ok) { if(ret->p) BN_free(ret->p); if(ret->q) BN_free(ret->q); if(ret->g) BN_free(ret->g); ret->p=BN_dup(p); ret->q=BN_dup(q); ret->g=BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok=0; goto err; } if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; if (seed_out) memcpy(seed_out, seed, qsize); } if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
/* signature verification */ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f,*ret; int i,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); return -1; } } if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num=BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if(!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } /* This check was for equality but PGP does evil things * and chops off the top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } if (BN_bin2bn(from,flen,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12)) if (!BN_sub(ret, rsa->n, ret)) goto err; p=buf; i=BN_bn2bin(ret,p); switch (padding) { case RSA_PKCS1_PADDING: r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num); break; case RSA_X931_PADDING: r=RSA_padding_check_X931(to,num,buf,i,num); break; case RSA_NO_PADDING: r=RSA_padding_check_none(to,num,buf,i,num); break; default: RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=-1; unsigned char *seed = NULL; unsigned char md[EVP_MAX_MD_SIZE]; int mdsize; BIGNUM *r0,*W,*X,*c,*test; BIGNUM *g=NULL,*q=NULL,*p=NULL; BN_MONT_CTX *mont=NULL; int i, k, n=0, m=0, qsize = N >> 3; int counter=0; int r=0; BN_CTX *ctx=NULL; unsigned int h=2; #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN2, FIPS_R_FIPS_SELFTEST_FAILED); goto err; } if (!fips_check_dsa_prng(ret, L, N)) goto err; #endif if (evpmd == NULL) { if (N == 160) evpmd = EVP_sha1(); else if (N == 224) evpmd = EVP_sha224(); else evpmd = EVP_sha256(); } mdsize = M_EVP_MD_size(evpmd); if (seed_len == 0) seed_len = mdsize; seed = OPENSSL_malloc(seed_len); if (!seed) goto err; if (seed_in) memcpy(seed, seed_in, seed_len); if ((ctx=BN_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test,BN_value_one(),L-1)) goto err; for (;;) { for (;;) /* find q */ { unsigned char *pmd; /* step 1 */ if(!BN_GENCB_call(cb, 0, m++)) goto err; if (!seed_in) { if (RAND_pseudo_bytes(seed, seed_len) < 0) goto err; } /* step 2 */ if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) goto err; /* Take least significant bits of md */ if (mdsize > qsize) pmd = md + mdsize - qsize; else pmd = md; if (mdsize < qsize) memset(md + mdsize, 0, qsize - mdsize); /* step 3 */ pmd[0] |= 0x80; pmd[qsize-1] |= 0x01; if (!BN_bin2bn(pmd, qsize, q)) goto err; /* step 4 */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_in ? 1 : 0, cb); if (r > 0) break; if (r != 0) goto err; /* Provided seed didn't produce a prime: error */ if (seed_in) { ok = 0; DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME); goto err; } /* do a callback call */ /* step 5 */ } /* Copy seed to seed_out before we mess with it */ if (seed_out) memcpy(seed_out, seed, seed_len); if(!BN_GENCB_call(cb, 2, 0)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; /* step 6 */ counter=0; /* "offset = 1" */ n=(L-1)/(mdsize << 3); for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) goto err; /* step 7 */ BN_zero(W); /* now 'buf' contains "SEED + offset - 1" */ for (k=0; k<=n; k++) { /* obtain "SEED + offset + k" by incrementing: */ for (i = seed_len-1; i >= 0; i--) { seed[i]++; if (seed[i] != 0) break; } if (!EVP_Digest(seed, seed_len, md ,NULL, evpmd, NULL)) goto err; /* step 8 */ if (!BN_bin2bn(md, mdsize, r0)) goto err; if (!BN_lshift(r0,r0,(mdsize << 3)*k)) goto err; if (!BN_add(W,W,r0)) goto err; } /* more of step 8 */ if (!BN_mask_bits(W,L-1)) goto err; if (!BN_copy(X,W)) goto err; if (!BN_add(X,X,test)) goto err; /* step 9 */ if (!BN_lshift1(r0,q)) goto err; if (!BN_mod(c,X,r0,ctx)) goto err; if (!BN_sub(r0,c,BN_value_one())) goto err; if (!BN_sub(p,X,r0)) goto err; /* step 10 */ if (BN_cmp(p,test) >= 0) { /* step 11 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ if (r != 0) goto err; } /* step 13 */ counter++; /* "offset = offset + n + 1" */ /* step 14 */ if (counter >= 4096) break; } } end: if(!BN_GENCB_call(cb, 2, 1)) goto err; /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; if (!BN_set_word(test,h)) goto err; if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; for (;;) { /* g=test^r0%p */ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test,test,BN_value_one())) goto err; h++; } if(!BN_GENCB_call(cb, 3, 1)) goto err; ok=1; err: if (ok == 1) { if(ret->p) BN_free(ret->p); if(ret->q) BN_free(ret->q); if(ret->g) BN_free(ret->g); ret->p=BN_dup(p); ret->q=BN_dup(q); ret->g=BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok=-1; goto err; } if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; } if (seed) OPENSSL_free(seed); if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
int StealthSecret(ec_secret& secret, ec_point& pubkey, const ec_point& pkSpend, ec_secret& sharedSOut, ec_point& pkOut) { /* send: secret = ephem_secret, pubkey = scan_pubkey receive: secret = scan_secret, pubkey = ephem_pubkey c = H(dP) Q = public scan key (EC point, 33 bytes) d = private scan key (integer, 32 bytes) R = public spend key f = private spend key Q = dG R = fG Sender (has Q and R, not d or f): P = eG c = H(eQ) = H(dP) R' = R + cG Recipient gets R' and P test 0 and infinity? */ int rv = 0; std::vector<uint8_t> vchOutQ; BN_CTX* bnCtx = NULL; BIGNUM* bnEphem = NULL; BIGNUM* bnQ = NULL; EC_POINT* Q = NULL; BIGNUM* bnOutQ = NULL; BIGNUM* bnc = NULL; EC_POINT* C = NULL; BIGNUM* bnR = NULL; EC_POINT* R = NULL; EC_POINT* Rout = NULL; BIGNUM* bnOutR = NULL; EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); if (!ecgrp) { printf("StealthSecret(): EC_GROUP_new_by_curve_name failed.\n"); return 1; }; if (!(bnCtx = BN_CTX_new())) { printf("StealthSecret(): BN_CTX_new failed.\n"); rv = 1; goto End; }; if (!(bnEphem = BN_bin2bn(&secret.e[0], ec_secret_size, BN_new()))) { printf("StealthSecret(): bnEphem BN_bin2bn failed.\n"); rv = 1; goto End; }; if (!(bnQ = BN_bin2bn(&pubkey[0], pubkey.size(), BN_new()))) { printf("StealthSecret(): bnQ BN_bin2bn failed\n"); rv = 1; goto End; }; if (!(Q = EC_POINT_bn2point(ecgrp, bnQ, NULL, bnCtx))) { printf("StealthSecret(): Q EC_POINT_bn2point failed\n"); rv = 1; goto End; }; // -- eQ // EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); // EC_POINT_mul calculates the value generator * n + q * m and stores the result in r. The value n may be NULL in which case the result is just q * m. if (!EC_POINT_mul(ecgrp, Q, NULL, Q, bnEphem, bnCtx)) { printf("StealthSecret(): eQ EC_POINT_mul failed\n"); rv = 1; goto End; }; if (!(bnOutQ = EC_POINT_point2bn(ecgrp, Q, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx))) { printf("StealthSecret(): Q EC_POINT_bn2point failed\n"); rv = 1; goto End; }; vchOutQ.resize(ec_compressed_size); if (BN_num_bytes(bnOutQ) != (int) ec_compressed_size || BN_bn2bin(bnOutQ, &vchOutQ[0]) != (int) ec_compressed_size) { printf("StealthSecret(): bnOutQ incorrect length.\n"); rv = 1; goto End; }; SHA256(&vchOutQ[0], vchOutQ.size(), &sharedSOut.e[0]); if (!(bnc = BN_bin2bn(&sharedSOut.e[0], ec_secret_size, BN_new()))) { printf("StealthSecret(): BN_bin2bn failed\n"); rv = 1; goto End; }; // -- cG if (!(C = EC_POINT_new(ecgrp))) { printf("StealthSecret(): C EC_POINT_new failed\n"); rv = 1; goto End; }; if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx)) { printf("StealthSecret(): C EC_POINT_mul failed\n"); rv = 1; goto End; }; if (!(bnR = BN_bin2bn(&pkSpend[0], pkSpend.size(), BN_new()))) { printf("StealthSecret(): bnR BN_bin2bn failed\n"); rv = 1; goto End; }; if (!(R = EC_POINT_bn2point(ecgrp, bnR, NULL, bnCtx))) { printf("StealthSecret(): R EC_POINT_bn2point failed\n"); rv = 1; goto End; }; if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx)) { printf("StealthSecret(): C EC_POINT_mul failed\n"); rv = 1; goto End; }; if (!(Rout = EC_POINT_new(ecgrp))) { printf("StealthSecret(): Rout EC_POINT_new failed\n"); rv = 1; goto End; }; if (!EC_POINT_add(ecgrp, Rout, R, C, bnCtx)) { printf("StealthSecret(): Rout EC_POINT_add failed\n"); rv = 1; goto End; }; if (!(bnOutR = EC_POINT_point2bn(ecgrp, Rout, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx))) { printf("StealthSecret(): Rout EC_POINT_bn2point failed\n"); rv = 1; goto End; }; pkOut.resize(ec_compressed_size); if (BN_num_bytes(bnOutR) != (int) ec_compressed_size || BN_bn2bin(bnOutR, &pkOut[0]) != (int) ec_compressed_size) { printf("StealthSecret(): pkOut incorrect length.\n"); rv = 1; goto End; }; End: if (bnOutR) BN_free(bnOutR); if (Rout) EC_POINT_free(Rout); if (R) EC_POINT_free(R); if (bnR) BN_free(bnR); if (C) EC_POINT_free(C); if (bnc) BN_free(bnc); if (bnOutQ) BN_free(bnOutQ); if (Q) EC_POINT_free(Q); if (bnQ) BN_free(bnQ); if (bnEphem) BN_free(bnEphem); if (bnCtx) BN_CTX_free(bnCtx); EC_GROUP_free(ecgrp); return rv; };
static int run_rfc5114_tests(void) { int i; DH *dhA = NULL; DH *dhB = NULL; unsigned char *Z1 = NULL; unsigned char *Z2 = NULL; const rfc5114_td *td = NULL; BIGNUM *bady = NULL; for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) { td = rfctd + i; /* Set up DH structures setting key components */ dhA = td->get_param(); dhB = td->get_param(); if ((dhA == NULL) || (dhB == NULL)) goto bad_err; dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, NULL); dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, NULL); dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, NULL); dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, NULL); if ((dhA->priv_key == NULL) || (dhA->pub_key == NULL) || (dhB->priv_key == NULL) || (dhB->pub_key == NULL)) goto bad_err; if ((td->Z_len != (size_t)DH_size(dhA)) || (td->Z_len != (size_t)DH_size(dhB))) goto err; Z1 = OPENSSL_malloc(DH_size(dhA)); Z2 = OPENSSL_malloc(DH_size(dhB)); if ((Z1 == NULL) || (Z2 == NULL)) goto bad_err; /* * Work out shared secrets using both sides and compare with expected * values. */ if (DH_compute_key(Z1, dhB->pub_key, dhA) == -1) goto bad_err; if (DH_compute_key(Z2, dhA->pub_key, dhB) == -1) goto bad_err; if (memcmp(Z1, td->Z, td->Z_len)) goto err; if (memcmp(Z2, td->Z, td->Z_len)) goto err; printf("RFC5114 parameter test %d OK\n", i + 1); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); dhA = NULL; dhB = NULL; Z1 = NULL; Z2 = NULL; } /* Now i == OSSL_NELEM(rfctd) */ /* RFC5114 uses unsafe primes, so now test an invalid y value */ dhA = DH_get_2048_224(); if (dhA == NULL) goto bad_err; Z1 = OPENSSL_malloc(DH_size(dhA)); if (Z1 == NULL) goto bad_err; bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y, sizeof(dhtest_rfc5114_2048_224_bad_y), NULL); if (bady == NULL) goto bad_err; if (!DH_generate_key(dhA)) goto bad_err; if (DH_compute_key(Z1, bady, dhA) != -1) { /* * DH_compute_key should fail with -1. If we get here we unexpectedly * allowed an invalid y value */ goto err; } /* We'll have a stale error on the queue from the above test so clear it */ ERR_clear_error(); printf("RFC5114 parameter test %d OK\n", i + 1); BN_free(bady); DH_free(dhA); OPENSSL_free(Z1); return 1; bad_err: BN_free(bady); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); fprintf(stderr, "Initalisation error RFC5114 set %d\n", i + 1); ERR_print_errors_fp(stderr); return 0; err: BN_free(bady); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); fprintf(stderr, "Test failed RFC5114 set %d\n", i + 1); return 0; }
int StealthSharedToSecretSpend(ec_secret& sharedS, ec_secret& spendSecret, ec_secret& secretOut) { int rv = 0; std::vector<uint8_t> vchOutP; BN_CTX* bnCtx = NULL; BIGNUM* bnc = NULL; BIGNUM* bnOrder = NULL; BIGNUM* bnSpend = NULL; EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); if (!ecgrp) { printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n"); return 1; }; if (!(bnCtx = BN_CTX_new())) { printf("StealthSecretSpend(): BN_CTX_new failed.\n"); rv = 1; goto End; }; if (!(bnc = BN_bin2bn(&sharedS.e[0], ec_secret_size, BN_new()))) { printf("StealthSecretSpend(): BN_bin2bn failed\n"); rv = 1; goto End; }; if (!(bnOrder = BN_new()) || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx)) { printf("StealthSecretSpend(): EC_GROUP_get_order failed\n"); rv = 1; goto End; }; if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new()))) { printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n"); rv = 1; goto End; }; //if (!BN_add(r, a, b)) return 0; //return BN_nnmod(r, r, m, ctx); if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx)) { printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n"); rv = 1; goto End; }; if (BN_is_zero(bnSpend)) // possible? { printf("StealthSecretSpend(): bnSpend is zero.\n"); rv = 1; goto End; }; if (BN_num_bytes(bnSpend) != (int) ec_secret_size || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size) { printf("StealthSecretSpend(): bnSpend incorrect length.\n"); rv = 1; goto End; }; End: if (bnSpend) BN_free(bnSpend); if (bnOrder) BN_free(bnOrder); if (bnc) BN_free(bnc); if (bnCtx) BN_CTX_free(bnCtx); EC_GROUP_free(ecgrp); return rv; };
int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* create and verify a ecdsa signature with every availble curve * (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) /* drop the curve */ { EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong length */ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* Modify a single byte of the signature: to ensure we don't * garble the ASN1 structure, we read the raw signature and * modify a byte in one of the bignums directly. */ sig_ptr = signature; if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(ecdsa_sig->r); s_len = BN_num_bytes(ecdsa_sig->s); bn_len = (degree + 7) / 8; if ((r_len > bn_len) || (s_len > bn_len)) { BIO_printf(out, " failed\n"); goto builtin_err; } buf_len = 2 * bn_len; if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) goto builtin_err; /* Pad the bignums with leading zeroes. */ memset(raw_buf, 0, buf_len); BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ /* clean bogus errors */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: if (eckey) EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (signature) OPENSSL_free(signature); if (raw_buf) OPENSSL_free(raw_buf); if (curves) OPENSSL_free(curves); return ret; }
static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; unsigned int length; #if USE_EVP EVP_PKEY *pkey; #endif isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); length = r.length; rsa = RSA_new(); if (rsa == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base; isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); e_bytes += *r.base; isc_region_consume(&r, 1); } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } rsa->e = BN_bin2bn(r.base, e_bytes, NULL); isc_region_consume(&r, e_bytes); rsa->n = BN_bin2bn(r.base, r.length, NULL); key->key_size = BN_num_bits(rsa->n); isc_buffer_forward(data, length); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) { RSA_free(rsa); return (ISC_R_NOMEMORY); } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); }
// Checks if the given password is valid bool Tester::check(const Memblock &mblock) { const String2Key &s2k = m_key.string2Key(); int32_t tmp = 0; // Generate key from password s2k.generateKey(mblock, m_keydata, m_keySize); // Decrypt first data block in order to check the first two bits of // the MPI. If they are correct, there's a good chance that the // password is correct, too. #if 1 memcpy(m_ivec, s2k.ivec(), m_blockSize); switch (m_cipher) { case CryptUtils::CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, m_keySize, m_keydata); CAST_cfb64_encrypt(m_in, m_out, CAST_BLOCK, &ck, m_ivec, &tmp, CAST_DECRYPT); } break; case CryptUtils::CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, m_keySize, m_keydata); BF_cfb64_encrypt(m_in, m_out, BF_BLOCK, &ck, m_ivec, &tmp, BF_DECRYPT); } break; case CryptUtils::CIPHER_AES128: case CryptUtils::CIPHER_AES192: case CryptUtils::CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(m_keydata, m_keySize * 8, &ck); AES_cfb128_encrypt(m_in, m_out, AES_BLOCK_SIZE, &ck, m_ivec, &tmp, AES_DECRYPT); } break; default: break; } uint32_t num_bits = ((m_out[0] << 8) | m_out[1]); if (num_bits < MIN_BN_BITS || num_bits > m_bits) { return false; } #endif // Decrypt all data memcpy(m_ivec, s2k.ivec(), m_blockSize); tmp = 0; switch (m_cipher) { case CryptUtils::CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, m_keySize, m_keydata); CAST_cfb64_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, CAST_DECRYPT); } break; case CryptUtils::CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, m_keySize, m_keydata); BF_cfb64_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, BF_DECRYPT); } break; case CryptUtils::CIPHER_AES128: case CryptUtils::CIPHER_AES192: case CryptUtils::CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(m_keydata, m_keySize * 8, &ck); AES_cfb128_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, AES_DECRYPT); } break; default: break; } // Verify bool checksumOk = false; switch (s2k.usage()) { case 254: { uint8_t checksum[SHA_DIGEST_LENGTH]; pgpry_SHA_CTX ctx; pgpry_SHA1_Init(&ctx); pgpry_SHA1_Update(&ctx, m_out, m_datalen - SHA_DIGEST_LENGTH); pgpry_SHA1_Final(checksum, &ctx); if (memcmp(checksum, m_out + m_datalen - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH) == 0) { checksumOk = true; } } break; case 0: case 255: { uint16_t sum = 0; for (uint32_t i = 0; i < m_datalen - 2; i++) { sum += m_out[i]; } if (sum == ((m_out[m_datalen - 2] << 8) | m_out[m_datalen - 1])) { checksumOk = true; } } break; default: break; } // If the checksum is ok, try to parse the first MPI of the private key if (checksumOk) { BIGNUM *b = NULL; uint32_t blen = (num_bits + 7) / 8; if (blen < m_datalen && ((b = BN_bin2bn(m_out + 2, blen, NULL)) != NULL)) { BN_free(b); return true; } } return false; }
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) { EC_GROUP *group = NULL; EC_POINT *P = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL; int ok = 0; int seed_len, param_len; const EC_METHOD *meth; const EC_CURVE_DATA *data; const unsigned char *params; /* If no curve data curve method must handle everything */ if (curve.data == NULL) return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL); if ((ctx = BN_CTX_new()) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } data = curve.data; seed_len = data->seed_len; param_len = data->param_len; params = (const unsigned char *)(data + 1); /* skip header */ params += seed_len; /* skip seed */ if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (curve.meth != 0) { meth = curve.meth(); if (((group = EC_GROUP_new(meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } else if (data->field_type == NID_X9_62_prime_field) { if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else { /* field_type == * NID_X9_62_characteristic_two_field */ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } #endif if ((P = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL || (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL || !BN_set_word(x, (BN_ULONG)data->cofactor)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_set_generator(group, P, order, x)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (seed_len) { if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } ok = 1; err: if (!ok) { EC_GROUP_free(group); group = NULL; } EC_POINT_free(P); BN_CTX_free(ctx); BN_free(p); BN_free(a); BN_free(b); BN_free(order); BN_free(x); BN_free(y); return group; }
void kexecdh_server(Kex *kex) { EC_POINT *client_public; EC_KEY *server_key; const EC_GROUP *group; BIGNUM *shared_secret; Key *server_host_private, *server_host_public; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf, *hash; u_int klen, slen, sbloblen, hashlen; int curve_nid; if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) fatal("%s: EC_KEY_new_by_curve_name failed", __func__); if (EC_KEY_generate_key(server_key) != 1) fatal("%s: EC_KEY_generate_key failed", __func__); group = EC_KEY_get0_group(server_key); #ifdef DEBUG_KEXECDH fputs("server private key:\n", stderr); key_dump_ec_key(server_key); #endif if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) fatal("Cannot load hostkey"); server_host_public = kex->load_host_public_key(kex->hostkey_type); if (server_host_public == NULL) fatal("Unsupported hostkey type %d", kex->hostkey_type); server_host_private = kex->load_host_private_key(kex->hostkey_type); if (server_host_private == NULL) fatal("Missing private key for hostkey type %d", kex->hostkey_type); debug("expecting SSH2_MSG_KEX_ECDH_INIT"); packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); if ((client_public = EC_POINT_new(group)) == NULL) fatal("%s: EC_POINT_new failed", __func__); packet_get_ecpoint(group, client_public); packet_check_eom(); if (key_ec_validate_public(group, client_public) != 0) fatal("%s: invalid client public key", __func__); #ifdef DEBUG_KEXECDH fputs("client public key:\n", stderr); key_dump_ec_point(group, client_public); #endif /* Calculate shared_secret */ klen = (EC_GROUP_get_degree(group) + 7) / 8; kbuf = xmalloc(klen); if (ECDH_compute_key(kbuf, klen, client_public, server_key, NULL) != (int)klen) fatal("%s: ECDH_compute_key failed", __func__); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, klen); #endif if ((shared_secret = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) fatal("%s: BN_bin2bn failed", __func__); memset(kbuf, 0, klen); xfree(kbuf); /* calc H */ key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); kex_ecdh_hash( kex->evp_md, group, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), buffer_ptr(&kex->my), buffer_len(&kex->my), server_host_key_blob, sbloblen, client_public, EC_KEY_get0_public_key(server_key), shared_secret, &hash, &hashlen ); EC_POINT_clear_free(client_public); /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, hashlen)) < 0) fatal("kexdh_server: key_sign failed"); /* destroy_sensitive_data(); */ /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ packet_start(SSH2_MSG_KEX_ECDH_REPLY); packet_put_string(server_host_key_blob, sbloblen); packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key)); packet_put_string(signature, slen); packet_send(); xfree(signature); xfree(server_host_key_blob); /* have keys, free server key */ EC_KEY_free(server_key); kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); }
static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j, num = 0, r = -1; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* * This check was for equality but PGP does evil things and chops off the * top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from, (int)flen, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } /* do the decrypt */ if ((rsa->flags & RSA_FLAG_EXT_PKEY) || (rsa->version == RSA_ASN1_VERSION_MULTI) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) { BN_free(d); goto err; } if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; j = BN_bn2binpad(ret, buf, num); switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); break; case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; case RSA_SSLV23_PADDING: r = RSA_padding_check_SSLv23(to, num, buf, j, num); break; case RSA_NO_PADDING: memcpy(to, buf, (r = j)); break; default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return r; }
int input_kex_dh_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; struct sshkey *server_host_public, *server_host_private; u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, kex->hostkey_nid, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, kex->hostkey_nid, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } /* key, cert */ if ((dh_client_pub = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_client_pub= "); BN_print_fp(stderr, dh_client_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_client_pub)); #endif #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { sshpkt_disconnect(ssh, "bad client public DH value"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = DH_size(kex->dh); if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || BN_bin2bn(kbuf, kout, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; /* calc H */ hashlen = sizeof(hash); if ((r = kex_dh_hash( kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, dh_client_pub, kex->dh->pub_key, shared_secret, hash, &hashlen)) != 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); kex->dh = NULL; if (dh_client_pub) BN_clear_free(dh_client_pub); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); free(server_host_key_blob); free(signature); return r; }