void SSL_SESSION_free(SSL_SESSION *ss) { int i; if (ss == NULL) return; CRYPTO_DOWN_REF(&ss->references, &i, ss->lock); REF_PRINT_COUNT("SSL_SESSION", ss); if (i > 0) return; REF_ASSERT_ISNT(i < 0); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key)); OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id)); X509_free(ss->peer); sk_X509_pop_free(ss->peer_chain, X509_free); sk_SSL_CIPHER_free(ss->ciphers); OPENSSL_free(ss->ext.hostname); OPENSSL_free(ss->ext.tick); #ifndef OPENSSL_NO_EC OPENSSL_free(ss->ext.ecpointformats); ss->ext.ecpointformats = NULL; ss->ext.ecpointformats_len = 0; OPENSSL_free(ss->ext.supportedgroups); ss->ext.supportedgroups = NULL; ss->ext.supportedgroups_len = 0; #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_PSK OPENSSL_free(ss->psk_identity_hint); OPENSSL_free(ss->psk_identity); #endif #ifndef OPENSSL_NO_SRP OPENSSL_free(ss->srp_username); #endif OPENSSL_free(ss->ext.alpn_selected); OPENSSL_free(ss->ticket_appdata); CRYPTO_THREAD_lock_free(ss->lock); OPENSSL_clear_free(ss, sizeof(*ss)); }
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type) { int ret; unsigned char *unipass; int uniplen; if (!pass) { unipass = NULL; uniplen = 0; } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); return 0; } ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); if (ret <= 0) return 0; OPENSSL_clear_free(unipass, uniplen); return ret; }
void EC_KEY_free(EC_KEY *r) { int i; if (r == NULL) return; i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); #ifdef REF_PRINT REF_PRINT("EC_KEY", r); #endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) { fprintf(stderr, "EC_KEY_free, bad reference count\n"); abort(); } #endif if (r->meth->finish != NULL) r->meth->finish(r); #ifndef OPENSSL_NO_ENGINE if (r->engine != NULL) ENGINE_finish(r->engine); #endif EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); EC_EX_DATA_free_all_data(&r->method_data); OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); }
/*- * returns * 1: correct signature * 0: incorrect signature * -1: error */ int DSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int siglen, DSA *dsa) { DSA_SIG *s; const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; int ret = -1; s = DSA_SIG_new(); if (s == NULL) return (ret); if (d2i_DSA_SIG(&s, &p, siglen) == NULL) goto err; /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_DSA_SIG(s, &der); if (derlen != siglen || memcmp(sigbuf, der, derlen)) goto err; ret = DSA_do_verify(dgst, dgst_len, s, dsa); err: OPENSSL_clear_free(der, derlen); DSA_SIG_free(s); return (ret); }
/*- * returns * 1: correct signature * 0: incorrect signature * -1: error */ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) { ECDSA_SIG *s; const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; int ret = -1; s = ECDSA_SIG_new(); if (s == NULL) return (ret); if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err; /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0) goto err; ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); err: OPENSSL_clear_free(der, derlen); ECDSA_SIG_free(s); return (ret); }
int RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { ASN1_OCTET_STRING sig; int i, j, ret = 1; unsigned char *p, *s; sig.type = V_ASN1_OCTET_STRING; sig.length = m_len; sig.data = (unsigned char *)m; i = i2d_ASN1_OCTET_STRING(&sig, NULL); j = RSA_size(rsa); if (i > (j - RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return (0); } s = OPENSSL_malloc((unsigned int)j + 1); if (s == NULL) { RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); return (0); } p = s; i2d_ASN1_OCTET_STRING(&sig, &p); i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); if (i <= 0) ret = 0; else *siglen = i; OPENSSL_clear_free(s, (unsigned int)j + 1); return (ret); }
int RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { X509_SIG sig; ASN1_TYPE parameter; int i, j, ret = 1; unsigned char *p, *tmps = NULL; const unsigned char *s = NULL; X509_ALGOR algor; ASN1_OCTET_STRING digest; if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); } /* Special case: SSL signature, just check the length */ if (type == NID_md5_sha1) { if (m_len != SSL_SIG_LENGTH) { RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); return (0); } i = SSL_SIG_LENGTH; s = m; } else { sig.algor = &algor; sig.algor->algorithm = OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) { RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); return (0); } if (OBJ_length(sig.algor->algorithm) == 0) { RSAerr(RSA_F_RSA_SIGN, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return (0); } parameter.type = V_ASN1_NULL; parameter.value.ptr = NULL; sig.algor->parameter = ¶meter; sig.digest = &digest; sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ sig.digest->length = m_len; i = i2d_X509_SIG(&sig, NULL); } j = RSA_size(rsa); if (i > (j - RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return (0); } if (type != NID_md5_sha1) { tmps = OPENSSL_malloc((unsigned int)j + 1); if (tmps == NULL) { RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE); return (0); } p = tmps; i2d_X509_SIG(&sig, &p); s = tmps; } i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); if (i <= 0) ret = 0; else *siglen = i; if (type != NID_md5_sha1) OPENSSL_clear_free(tmps, (unsigned int)j + 1); return (ret); }
int EVP_PBE_scrypt(const char *pass, size_t passlen, const unsigned char *salt, size_t saltlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen) { int rv = 0; unsigned char *B; uint32_t *X, *V, *T; uint64_t i, Blen, Vlen; /* Sanity check parameters */ /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) return 0; /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ if (p > SCRYPT_PR_MAX / r) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* * Need to check N: if 2^(128 * r / 8) overflows limit this is * automatically satisfied since N <= UINT64_MAX. */ if (16 * r <= LOG2_UINT64_MAX) { if (N >= (((uint64_t)1) << (16 * r))) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } } /* Memory checks: check total allocated buffer size fits in uint64_t */ /* * B size in section 5 step 1.S * Note: we know p * 128 * r < UINT64_MAX because we already checked * p * r < SCRYPT_PR_MAX */ Blen = p * 128 * r; /* * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] */ if (Blen > INT_MAX) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t * This is combined size V, X and T (section 4) */ i = UINT64_MAX / (32 * sizeof(uint32_t)); if (N + 2 > i / r) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } Vlen = 32 * r * (N + 2) * sizeof(uint32_t); /* check total allocated size fits in uint64_t */ if (Blen > UINT64_MAX - Vlen) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; /* Check that the maximum memory doesn't exceed a size_t limits */ if (maxmem > SIZE_MAX) maxmem = SIZE_MAX; if (Blen + Vlen > maxmem) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* If no key return to indicate parameters are OK */ if (key == NULL) return 1; B = OPENSSL_malloc((size_t)(Blen + Vlen)); if (B == NULL) { EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE); return 0; } X = (uint32_t *)(B + Blen); T = X + 32 * r; V = T + 32 * r; if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), (int)Blen, B) == 0) goto err; for (i = 0; i < p; i++) scryptROMix(B + 128 * r * i, r, N, X, T, V); if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), keylen, key) == 0) goto err; rv = 1; err: if (rv == 0) EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR); OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); return rv; }
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) { BIO *b; EVP_CIPHER_CTX *ctx; const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; size_t tkeylen = 0; int ok = 0; int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; b = BIO_new(BIO_f_cipher()); if (!b) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); return NULL; } BIO_get_cipher_ctx(b, &ctx); if (enc) { ciph = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ if (ec->key) ec->cipher = NULL; } else { ciph = EVP_get_cipherbyobj(calg->algorithm); if (!ciph) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); goto err; } } if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { int ivlen; calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { if (RAND_bytes(iv, ivlen) <= 0) goto err; piv = iv; } } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } tkeylen = EVP_CIPHER_CTX_key_length(ctx); /* Generate random session key */ if (!enc || !ec->key) { tkey = OPENSSL_malloc(tkeylen); if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; } if (!ec->key) { ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; if (enc) keep_key = 1; else ERR_clear_error(); } if (ec->keylen != tkeylen) { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { /* * Only reveal failure if debugging so we don't leak information * which may be useful in MMA. */ if (enc || ec->debug) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_INVALID_KEY_LENGTH); goto err; } else { /* Use random key */ OPENSSL_clear_free(ec->key, ec->keylen); ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; ERR_clear_error(); } } } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (piv) { calg->parameter = ASN1_TYPE_new(); if (!calg->parameter) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } } ok = 1; err: if (!keep_key) { OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; } OPENSSL_clear_free(tkey, tkeylen); if (ok) return b; BIO_free(b); return NULL; }
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; unsigned char *p, *data = NULL; const char *objstr = NULL; char buf[PEM_BUFSIZE]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0 || EVP_CIPHER_iv_length(enc) > (int)sizeof(iv) /* * Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n" * fits into buf */ || (strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13) > sizeof(buf)) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize = i2d(x, NULL)) < 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); dsize = 0; goto err; } /* dsize + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data = OPENSSL_malloc((unsigned int)dsize + 20); if (data == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); goto err; } p = data; i = i2d(x, &p); if (enc != NULL) { if (kstr == NULL) { if (callback == NULL) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); else klen = (*callback) (buf, PEM_BUFSIZE, 1, u); if (klen <= 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen); #endif kstr = (unsigned char *)buf; } if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */ goto err; /* * The 'iv' is used as the iv and as a salt. It is NOT taken from * the BytesToKey function */ if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) goto err; if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf, PEM_BUFSIZE); buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv); /* k=strlen(buf); */ ret = 1; if ((ctx = EVP_CIPHER_CTX_new()) == NULL || !EVP_EncryptInit_ex(ctx, enc, NULL, key, iv) || !EVP_EncryptUpdate(ctx, data, &j, data, i) || !EVP_EncryptFinal_ex(ctx, &(data[j]), &i)) ret = 0; if (ret == 0) goto err; i += j; } else { ret = 1; buf[0] = '\0'; } i = PEM_write_bio(bp, name, buf, data, i); if (i <= 0) ret = 0; err: OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(iv, sizeof(iv)); EVP_CIPHER_CTX_free(ctx); OPENSSL_cleanse(buf, PEM_BUFSIZE); OPENSSL_clear_free(data, (unsigned int)dsize); return ret; }
static void sha256_freectx(void *vctx) { SHA256_CTX *ctx = (SHA256_CTX *)vctx; OPENSSL_clear_free(ctx, sizeof(*ctx)); }
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; int slen; EVP_PKEY *ret = NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if (!p8) goto p8err; if (cb) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen <= 0) { PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); if (!ameth || !ameth->old_priv_decode) goto p8err; ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); err: OPENSSL_free(nm); OPENSSL_clear_free(data, len); return (ret); }
static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) { unsigned char *buf = NULL; int ret = 0, bit, bytes, mask; time_t tim; if (bits == 0) { BN_zero(rnd); return 1; } bytes = (bits + 7) / 8; bit = (bits - 1) % 8; mask = 0xff << (bit + 1); buf = OPENSSL_malloc(bytes); if (buf == NULL) { BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); goto err; } /* make a random number and set the top and bottom bits */ time(&tim); RAND_add(&tim, sizeof(tim), 0.0); if (pseudorand) { if (RAND_bytes(buf, bytes) <= 0) goto err; } else { if (RAND_bytes(buf, bytes) <= 0) goto err; } if (pseudorand == 2) { /* * generate patterns that are more likely to trigger BN library bugs */ int i; unsigned char c; for (i = 0; i < bytes; i++) { if (RAND_bytes(&c, 1) <= 0) goto err; if (c >= 128 && i > 0) buf[i] = buf[i - 1]; else if (c < 42) buf[i] = 0; else if (c < 84) buf[i] = 255; } } if (top != -1) { if (top) { if (bit == 0) { buf[0] = 1; buf[1] |= 0x80; } else { buf[0] |= (3 << (bit - 1)); } } else { buf[0] |= (1 << bit); } } buf[0] &= ~mask; if (bottom) /* set bottom bit if requested */ buf[bytes - 1] |= 1; if (!BN_bin2bn(buf, bytes, rnd)) goto err; ret = 1; err: OPENSSL_clear_free(buf, bytes); bn_check_top(rnd); return (ret); }
static int rsa_ossl_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_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_OSSL_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_OSSL_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 (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_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; case RSA_PKCS1_OAEP_PADDING: i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); break; 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_OSSL_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_OSSL_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, rsa->lock, 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); OPENSSL_clear_free(buf, num); return r; }
/* signature verification */ static int rsa_ossl_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_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_OSSL_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_OSSL_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 (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_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_OSSL_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_OSSL_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, rsa->lock, 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_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_OSSL_PUBLIC_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; }
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 *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 (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; 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; 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: r = RSA_padding_check_none(to, num, buf, j, num); 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; }
/* 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, 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 (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_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->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; 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); OPENSSL_clear_free(buf, num); return r; }
static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; EVP_PKEY *pkey = ktri->pkey; unsigned char *ek = NULL; size_t eklen; int ret = 0; CMS_EncryptedContentInfo *ec; ec = cms->d.envelopedData->encryptedContentInfo; if (ktri->pkey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); return 0; } ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ktri->pctx) return 0; if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; if (!cms_env_asn1_ctrl(ri, 1)) goto err; if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); goto err; } if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, ktri->encryptedKey->data, ktri->encryptedKey->length) <= 0) goto err; ek = OPENSSL_malloc(eklen); if (ek == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, ktri->encryptedKey->data, ktri->encryptedKey->length) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); goto err; } ret = 1; OPENSSL_clear_free(ec->key, ec->keylen); ec->key = ek; ec->keylen = eklen; err: EVP_PKEY_CTX_free(ktri->pctx); ktri->pctx = NULL; if (!ret) OPENSSL_free(ek); return ret; }
static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { HKDF_PKEY_CTX *kctx = ctx->data; switch (type) { case EVP_PKEY_CTRL_HKDF_MD: if (p2 == NULL) return 0; kctx->md = p2; return 1; case EVP_PKEY_CTRL_HKDF_MODE: kctx->mode = p1; return 1; case EVP_PKEY_CTRL_HKDF_SALT: if (p1 == 0 || p2 == NULL) return 1; if (p1 < 0) return 0; if (kctx->salt != NULL) OPENSSL_clear_free(kctx->salt, kctx->salt_len); kctx->salt = OPENSSL_memdup(p2, p1); if (kctx->salt == NULL) return 0; kctx->salt_len = p1; return 1; case EVP_PKEY_CTRL_HKDF_KEY: if (p1 < 0) return 0; if (kctx->key != NULL) OPENSSL_clear_free(kctx->key, kctx->key_len); kctx->key = OPENSSL_memdup(p2, p1); if (kctx->key == NULL) return 0; kctx->key_len = p1; return 1; case EVP_PKEY_CTRL_HKDF_INFO: if (p1 == 0 || p2 == NULL) return 1; if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) return 0; memcpy(kctx->info + kctx->info_len, p2, p1); kctx->info_len += p1; return 1; default: return -2; } }
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX *ctx = NULL; unsigned char *buf_in = NULL; int ret = -1, inl; int mdnid, pknid; if (!pkey) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); return -1; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); return -1; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } /* Convert signature OID into digest and public key OIDs */ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } if (mdnid == NID_undef) { if (!pkey->ameth || !pkey->ameth->item_verify) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey); /* * Return value of 2 means carry on, anything else means we exit * straight away: either a fatal error of the underlying verification * routine handles all verification. */ if (ret != 2) goto err; ret = -1; } else { const EVP_MD *type; type = EVP_get_digestbynid(mdnid); if (type == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } /* Check public key OID matches public key type */ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); goto err; } if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); ret = 0; goto err; } } inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl); OPENSSL_clear_free(buf_in, (unsigned int)inl); if (!ret) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); goto err; } ret = -1; if (EVP_DigestVerifyFinal(ctx, signature->data, (size_t)signature->length) <= 0) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); ret = 0; goto err; } ret = 1; err: EVP_MD_CTX_free(ctx); return (ret); }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i, j; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); return NULL; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: /* * p7->d.sign->contents is a PKCS7 structure consisting of a contentType * field and optional content. * data_body is NULL if that structure has no (=detached) content * or if the contentType is wrong (i.e., not "data"). */ data_body = PKCS7_get_octet_string(p7->d.sign->contents); if (!PKCS7_is_detached(p7) && data_body == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_SIGNED_DATA_TYPE); goto err; } md_sk = p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.enveloped->enc_data->enc_data; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* Detached content must be supplied via in_bio instead. */ if (data_body == NULL && in_bio == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } j = OBJ_obj2nid(xa->algorithm); evp_md = EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp, evp_md); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } } if (evp_cipher != NULL) { if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } /* * It was encrypted, we need to decrypt the secret key with the * private key */ /* * Find the recipientInfo which matches the passed certificate (if * any) */ if (pcert) { for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { /* * Always attempt to decrypt all rinfo even after success as a * defence against MMA timing attacks. */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } } else { /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) goto err; /* Generate random key as MMA defence */ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); tkey = OPENSSL_malloc(tkeylen); if (!tkey) goto err; if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) goto err; if (ek == NULL) { ek = tkey; eklen = tkeylen; tkey = NULL; } if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* * Some S/MIME clients don't use the same key and effective key * length. The key length is determined by the size of the * decrypted RSA key. */ if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { /* Use random key as MMA defence */ OPENSSL_clear_free(ek, eklen); ek = tkey; eklen = tkeylen; tkey = NULL; } } /* Clear errors so we don't leak information useful in MMA */ ERR_clear_error(); if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) goto err; OPENSSL_clear_free(ek, eklen); ek = NULL; OPENSSL_clear_free(tkey, tkeylen); tkey = NULL; if (out == NULL) out = etmp; else BIO_push(out, etmp); etmp = NULL; } if (in_bio != NULL) { bio = in_bio; } else { if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data, data_body->length); else { bio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio, 0); } if (bio == NULL) goto err; } BIO_push(out, bio); bio = NULL; return out; err: OPENSSL_clear_free(ek, eklen); OPENSSL_clear_free(tkey, tkeylen); BIO_free_all(out); BIO_free_all(btmp); BIO_free_all(etmp); BIO_free_all(bio); return NULL; }
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, const EVP_MD *type) { EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char *p, *buf_in = NULL, *buf_out = NULL; int i, inl = 0, outl = 0, outll = 0; X509_ALGOR *a; if (ctx == NULL) { ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); goto err; } for (i = 0; i < 2; i++) { if (i == 0) a = algor1; else a = algor2; if (a == NULL) continue; if (type->pkey_type == NID_dsaWithSHA1) { /* * special case: RFC 2459 tells us to omit 'parameters' with * id-dsa-with-sha1 */ ASN1_TYPE_free(a->parameter); a->parameter = NULL; } else if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); if ((a->parameter = ASN1_TYPE_new()) == NULL) goto err; a->parameter->type = V_ASN1_NULL; } ASN1_OBJECT_free(a->algorithm); a->algorithm = OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } inl = i2d(data, NULL); buf_in = OPENSSL_malloc((unsigned int)inl); outll = outl = EVP_PKEY_size(pkey); buf_out = OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); if (!EVP_SignInit_ex(ctx, type, NULL) || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl) || !EVP_SignFinal(ctx, (unsigned char *)buf_out, (unsigned int *)&outl, pkey)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); goto err; } OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_free(ctx); OPENSSL_clear_free((char *)buf_in, (unsigned int)inl); OPENSSL_clear_free((char *)buf_out, outll); return (outl); }
void ssl3_cleanup_key_block(SSL *s) { OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length); s->s3->tmp.key_block = NULL; s->s3->tmp.key_block_length = 0; }
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) { const EVP_MD *type; EVP_PKEY *pkey; unsigned char *buf_in = NULL, *buf_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype; int rv; type = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); if (!type || !pkey) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (pkey->ameth->item_sign) { rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); if (rv == 1) outl = signature->length; /*- * Return value meanings: * <=0: error. * 1: method does everything. * 2: carry on as normal. * 3: ASN1 method sets algorithm identifiers: just sign. */ if (rv <= 0) ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); if (rv <= 1) goto err; } else rv = 2; if (rv == 2) { if (!pkey->ameth || !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey->ameth->pkey_id)) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) paramtype = V_ASN1_NULL; else paramtype = V_ASN1_UNDEF; if (algor1) X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); if (algor2) X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); } inl = ASN1_item_i2d(asn, &buf_in, it); outll = outl = EVP_PKEY_size(pkey); buf_out = OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestSignUpdate(ctx, buf_in, inl) || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); goto err; } OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_free(ctx); OPENSSL_clear_free((char *)buf_in, (unsigned int)inl); OPENSSL_clear_free((char *)buf_out, outll); return (outl); }
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX *ctx = NULL; if (mgf1Hash == NULL) mgf1Hash = Hash; hLen = EVP_MD_size(Hash); if (hLen < 0) goto err; /*- * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is maximized * -N reserved */ if (sLen == -1) sLen = hLen; else if (sLen == -2) sLen = -2; else if (sLen < -2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (MSBits == 0) { *EM++ = 0; emLen--; } if (emLen < hLen + 2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen == -2) { sLen = emLen - hLen - 2; } else if (sLen > emLen - hLen - 2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (salt == NULL) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); goto err; } if (RAND_bytes(salt, sLen) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; ctx = EVP_MD_CTX_new(); if (ctx == NULL) goto err; if (!EVP_DigestInit_ex(ctx, Hash, NULL) || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) || !EVP_DigestUpdate(ctx, mHash, hLen)) goto err; if (sLen && !EVP_DigestUpdate(ctx, salt, sLen)) goto err; if (!EVP_DigestFinal_ex(ctx, H, NULL)) goto err; /* Generate dbMask in place then perform XOR on it */ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) goto err; p = EM; /* * Initial PS XORs with all zeroes which is a NOP so just update pointer. * Note from a test above this value is guaranteed to be non-negative. */ p += emLen - sLen - hLen - 2; *p++ ^= 0x1; if (sLen > 0) { for (i = 0; i < sLen; i++) *p++ ^= salt[i]; } if (MSBits) EM[0] &= 0xFF >> (8 - MSBits); /* H is already in place so just set final 0xbc */ EM[emLen - 1] = 0xbc; ret = 1; err: EVP_MD_CTX_free(ctx); OPENSSL_clear_free(salt, sLen); return ret; }
int mac_main(int argc, char **argv) { int ret = 1; char *prog; const EVP_MAC *mac = NULL; OPTION_CHOICE o; EVP_MAC_CTX *ctx = NULL; STACK_OF(OPENSSL_STRING) *opts = NULL; unsigned char *buf = NULL; size_t len; int i; BIO *in = NULL, *out = NULL; const char *outfile = NULL; const char *infile = NULL; int out_bin = 0; int inform = FORMAT_BINARY; prog = opt_init(argc, argv, mac_options); buf = app_malloc(BUFSIZE, "I/O buffer"); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto err; case OPT_HELP: opt_help(mac_options); ret = 0; goto err; case OPT_BIN: out_bin = 1; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_MACOPT: if (opts == NULL) opts = sk_OPENSSL_STRING_new_null(); if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) goto opthelp; break; } } argc = opt_num_rest(); argv = opt_rest(); if (argc != 1) { BIO_printf(bio_err, "Invalid number of extra arguments\n"); goto opthelp; } mac = EVP_get_macbyname(argv[0]); if (mac == NULL) { BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]); goto opthelp; } ctx = EVP_MAC_CTX_new(mac); if (ctx == NULL) goto err; if (opts != NULL) { for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { char *opt = sk_OPENSSL_STRING_value(opts, i); if (mac_ctrl_string(ctx, opt) <= 0) { BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); ERR_print_errors(bio_err); goto err; } } } /* Use text mode for stdin */ if (infile == NULL || strcmp(infile, "-") == 0) inform = FORMAT_TEXT; in = bio_open_default(infile, 'r', inform); if (in == NULL) goto err; out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); if (out == NULL) goto err; if (!EVP_MAC_init(ctx)) { BIO_printf(bio_err, "EVP_MAC_Init failed\n"); goto err; } for (;;) { i = BIO_read(in, (char *)buf, BUFSIZE); if (i < 0) { BIO_printf(bio_err, "Read Error in '%s'\n", infile); goto err; } if (i == 0) break; if (!EVP_MAC_update(ctx, buf, i)) { BIO_printf(bio_err, "EVP_MAC_update failed\n"); goto err; } } if (!EVP_MAC_final(ctx, NULL, &len)) { BIO_printf(bio_err, "EVP_MAC_final failed\n"); goto err; } if (len > BUFSIZE) { BIO_printf(bio_err, "output len is too large\n"); goto err; } if (!EVP_MAC_final(ctx, buf, &len)) { BIO_printf(bio_err, "EVP_MAC_final failed\n"); goto err; } if (out_bin) { BIO_write(out, buf, len); } else { if (outfile == NULL) BIO_printf(out,"\n"); for (i = 0; i < (int)len; ++i) BIO_printf(out, "%02X", buf[i]); if (outfile == NULL) BIO_printf(out,"\n"); } ret = 0; err: if (ret != 0) ERR_print_errors(bio_err); OPENSSL_clear_free(buf, BUFSIZE); sk_OPENSSL_STRING_free(opts); BIO_free(in); BIO_free(out); EVP_MAC_CTX_free(ctx); return ret; }
int PEM_write_bio(BIO *bp, const char *name, const char *header, const unsigned char *data, long len) { int nlen, n, i, j, outl; unsigned char *buf = NULL; EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); int reason = ERR_R_BUF_LIB; int retval = 0; if (ctx == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } EVP_EncodeInit(ctx); nlen = strlen(name); if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || (BIO_write(bp, name, nlen) != nlen) || (BIO_write(bp, "-----\n", 6) != 6)) goto err; i = strlen(header); if (i > 0) { if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) goto err; } buf = OPENSSL_malloc(PEM_BUFSIZE * 8); if (buf == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } i = j = 0; while (len > 0) { n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); if (!EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n)) goto err; if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) goto err; i += outl; len -= n; j += n; } EVP_EncodeFinal(ctx, buf, &outl); if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) goto err; if ((BIO_write(bp, "-----END ", 9) != 9) || (BIO_write(bp, name, nlen) != nlen) || (BIO_write(bp, "-----\n", 6) != 6)) goto err; retval = i + outl; err: if (retval == 0) PEMerr(PEM_F_PEM_WRITE_BIO, reason); EVP_ENCODE_CTX_free(ctx); OPENSSL_clear_free(buf, PEM_BUFSIZE * 8); return retval; }
int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { int i, ret = 0, sigtype; unsigned char *s; X509_SIG *sig = NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); return (0); } if ((dtype == NID_md5_sha1) && rm) { i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa, RSA_PKCS1_PADDING); if (i <= 0) return 0; *prm_len = i; return 1; } s = OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); if (i <= 0) goto err; /* * Oddball MDC2 case: signature can be OCTET STRING. check for correct * tag and length octets. */ if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { if (rm) { memcpy(rm, s + 2, 16); *prm_len = 16; ret = 1; } else if (memcmp(m, s + 2, 16)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); else ret = 1; } /* Special case: SSL signature */ if (dtype == NID_md5_sha1) { if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p = s; sig = d2i_X509_SIG(NULL, &p, (long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } /* * Parameters to the signature algorithm can also be used to create * forgeries */ if (sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } sigtype = OBJ_obj2nid(sig->algor->algorithm); #ifdef RSA_DEBUG /* put a backward compatibility flag in EAY */ fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), OBJ_nid2ln(dtype)); #endif if (sigtype != dtype) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } if (rm) { const EVP_MD *md; md = EVP_get_digestbynid(dtype); if (md && (EVP_MD_size(md) != sig->digest->length)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); else { memcpy(rm, sig->digest->data, sig->digest->length); *prm_len = sig->digest->length; ret = 1; } } else if (((unsigned int)sig->digest->length != m_len) || (memcmp(m, sig->digest->data, m_len) != 0)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); } else ret = 1; } err: X509_SIG_free(sig); OPENSSL_clear_free(s, (unsigned int)siglen); return (ret); }
int dgst_main(int argc, char **argv) { BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; ENGINE *e = NULL, *impl = NULL; EVP_PKEY *sigkey = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; char *hmac_key = NULL; char *mac_name = NULL; char *passinarg = NULL, *passin = NULL; const EVP_MD *md = NULL, *m; const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL, *randfile = NULL; OPTION_CHOICE o; int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0, non_fips_allow = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); md = EVP_get_digestbyname(prog); prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dgst_options); ret = 0; goto end; case OPT_C: separator = 1; break; case OPT_R: separator = 2; break; case OPT_RAND: randfile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_SIGN: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_VERIFY: keyfile = opt_arg(); want_pub = do_verify = 1; break; case OPT_PRVERIFY: keyfile = opt_arg(); do_verify = 1; break; case OPT_SIGNATURE: sigfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ENGINE_IMPL: engine_impl = 1; break; case OPT_HEX: out_bin = 0; break; case OPT_BINARY: out_bin = 1; break; case OPT_DEBUG: debug = 1; break; case OPT_FIPS_FINGERPRINT: hmac_key = "etaonrishdlcupfm"; break; case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; break; case OPT_HMAC: hmac_key = opt_arg(); break; case OPT_MAC: mac_name = opt_arg(); break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; case OPT_MACOPT: if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) goto opthelp; break; case OPT_DIGEST: if (!opt_md(opt_unknown(), &m)) goto opthelp; md = m; break; } } argc = opt_num_rest(); argv = opt_rest(); if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if (engine_impl) impl = e; in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); if ((in == NULL) || (bmd == NULL)) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in, BIO_debug_callback); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *)bio_err); } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (out_bin == -1) { if (keyfile) out_bin = 1; else out_bin = 0; } if (randfile) app_RAND_load_file(randfile, 0); out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); if (out == NULL) goto end; if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; } if (keyfile) { if (want_pub) sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate message */ goto end; } } if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) goto mac_end; if (macopts) { char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { macopt = sk_OPENSSL_STRING_value(macopts, i); if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); ERR_print_errors(bio_err); goto mac_end; } } } if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto mac_end; } r = 1; mac_end: EVP_PKEY_CTX_free(mac_ctx); if (r == 0) goto end; } if (non_fips_allow) { EVP_MD_CTX *md_ctx; BIO_get_md_ctx(bmd, &md_ctx); EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } if (hmac_key) { sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, (unsigned char *)hmac_key, -1); if (!sigkey) goto end; } if (sigkey) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; int r; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (do_verify) r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); if (!r) { BIO_printf(bio_err, "Error setting context\n"); ERR_print_errors(bio_err); goto end; } if (sigopts) { char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pctx, sigopt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); goto end; } } } } /* we use md as a filter, reading from 'in' */ else { EVP_MD_CTX *mctx = NULL; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (md == NULL) md = EVP_md5(); if (!EVP_DigestInit_ex(mctx, md, impl)) { BIO_printf(bio_err, "Error setting digest\n"); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } siglen = EVP_PKEY_size(sigkey); sigbuf = app_malloc(siglen, "signature buffer"); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } } inp = BIO_push(bmd, in); if (md == NULL) { EVP_MD_CTX *tctx; BIO_get_md_ctx(bmd, &tctx); md = EVP_MD_CTX_md(tctx); } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin", bmd); } else { const char *md_name = NULL, *sig_name = NULL; if (!out_bin) { if (sigkey) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_get0_asn1(sigkey); if (ameth) EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &sig_name, ameth); } if (md) md_name = EVP_MD_name(md); } ret = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); ret++; continue; } else r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i], bmd); if (r) ret = r; (void)BIO_reset(bmd); } } end: OPENSSL_clear_free(buf, BUFSIZE); BIO_free(in); OPENSSL_free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); sk_OPENSSL_STRING_free(sigopts); sk_OPENSSL_STRING_free(macopts); OPENSSL_free(sigbuf); BIO_free(bmd); return (ret); }
int EVP_PBE_scrypt(const char *pass, size_t passlen, const unsigned char *salt, size_t saltlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen) { int rv = 0; unsigned char *B; uint32_t *X, *V, *T; uint64_t i, Blen, Vlen; /* Sanity check parameters */ /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) return 0; /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ if (p > SCRYPT_PR_MAX / r) return 0; /* * Need to check N: if 2^(128 * r / 8) overflows limit this is * automatically satisfied since N <= UINT64_MAX. */ if (16 * r <= LOG2_UINT64_MAX) { if (N >= (1UL << (16 * r))) return 0; } /* Memory checks: check total allocated buffer size fits in uint64_t */ /* * B size in section 5 step 1.S * Note: we know p * 128 * r < UINT64_MAX because we already checked * p * r < SCRYPT_PR_MAX */ Blen = p * 128 * r; /* * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t. * This is combined size V, X and T (section 4) */ i = UINT64_MAX / (32 * sizeof(uint32_t)); if (N + 2 > i / r) return 0; Vlen = 32 * r * (N + 2) * sizeof(uint32_t); /* check total allocated size fits in uint64_t */ if (Blen > UINT64_MAX - Vlen) return 0; if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; if (Blen + Vlen > maxmem) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* If no key return to indicate parameters are OK */ if (key == NULL) return 1; B = OPENSSL_malloc(Blen + Vlen); if (B == NULL) return 0; X = (uint32_t *)(B + Blen); T = X + 32 * r; V = T + 32 * r; if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), Blen, B) == 0) goto err; for (i = 0; i < p; i++) scryptROMix(B + 128 * r * i, r, N, X, T, V); if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(), keylen, key) == 0) goto err; rv = 1; #ifdef SCRYPT_DEBUG fprintf(stderr, "scrypt parameters:\n"); fprintf(stderr, "N=%lu, p=%lu, r=%lu\n", N, p, r); fprintf(stderr, "Salt:\n"); BIO_dump_fp(stderr, (char *)salt, saltlen); fprintf(stderr, "Password:\n"); BIO_dump_fp(stderr, (char *)pass, passlen); fprintf(stderr, "Key:\n"); BIO_dump_fp(stderr, (char *)key, keylen); #endif err: OPENSSL_clear_free(B, Blen + Vlen); return rv; }