int RSA_print(BIO *bp, const RSA *x, int off) { char str[128]; const char *s; unsigned char *m=NULL; int ret=0, mod_len = 0; size_t buf_len=0, i; if (x->n) buf_len = (size_t)BN_num_bytes(x->n); if (x->e) if (buf_len < (i = (size_t)BN_num_bytes(x->e))) buf_len = i; if (x->d) if (buf_len < (i = (size_t)BN_num_bytes(x->d))) buf_len = i; if (x->p) if (buf_len < (i = (size_t)BN_num_bytes(x->p))) buf_len = i; if (x->q) if (buf_len < (i = (size_t)BN_num_bytes(x->q))) buf_len = i; if (x->dmp1) if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1))) buf_len = i; if (x->dmq1) if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1))) buf_len = i; if (x->iqmp) if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp))) buf_len = i; m=(unsigned char *)OPENSSL_malloc(buf_len+10); if (m == NULL) { RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE); goto err; } if (x->n != NULL) mod_len = BN_num_bits(x->n); if (x->d != NULL) { if(!BIO_indent(bp,off,128)) goto err; if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) <= 0) goto err; } if (x->d == NULL) BIO_snprintf(str,sizeof str,"Modulus (%d bit):", mod_len); else BUF_strlcpy(str,"modulus:",sizeof str); if (!print(bp,str,x->n,m,off)) goto err; s=(x->d == NULL)?"Exponent:":"publicExponent:"; if ((x->e != NULL) && !print(bp,s,x->e,m,off)) goto err; if ((x->d != NULL) && !print(bp,"privateExponent:",x->d,m,off)) goto err; if ((x->p != NULL) && !print(bp,"prime1:",x->p,m,off)) goto err; if ((x->q != NULL) && !print(bp,"prime2:",x->q,m,off)) goto err; if ((x->dmp1 != NULL) && !print(bp,"exponent1:",x->dmp1,m,off)) goto err; if ((x->dmq1 != NULL) && !print(bp,"exponent2:",x->dmq1,m,off)) goto err; if ((x->iqmp != NULL) && !print(bp,"coefficient:",x->iqmp,m,off)) goto err; ret=1; err: if (m != NULL) OPENSSL_free(m); return(ret); }
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; 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, 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 (sLen == -2) { sLen = emLen - hLen - 2; } else if (emLen < (hLen + sLen + 2)) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = (unsigned char*)OPENSSL_malloc(sLen); if (!salt) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } if (RAND_bytes(salt, sLen) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; EVP_MD_CTX_init(&ctx); EVP_DigestInit_ex(&ctx, Hash, NULL); EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes); EVP_DigestUpdate(&ctx, mHash, hLen); if (sLen) EVP_DigestUpdate(&ctx, salt, sLen); EVP_DigestFinal(&ctx, H, NULL); EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash)) 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: if (salt) OPENSSL_free(salt); return ret; }
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM *local_n = NULL; BIGNUM *e, *n; BN_CTX *ctx; BN_BLINDING *ret = NULL; if (in_ctx == NULL) { if ((ctx = BN_CTX_new()) == NULL) return 0; } else ctx = in_ctx; BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else e = rsa->e; if ((RAND_status() == 0) && rsa->d != NULL && bn_get_words(rsa->d) != NULL) { /* * if PRNG is not properly seeded, resort to secret exponent as * unpredictable seed */ RAND_add(bn_get_words(rsa->d), bn_get_dmax(rsa->d) * sizeof(BN_ULONG), 0.0); } if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { /* Set BN_FLG_CONSTTIME flag */ local_n = n = BN_new(); if (!local_n) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); } else n = rsa->n; ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); if (ret == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) BN_CTX_free(ctx); if (rsa->e == NULL) BN_free(e); if (local_n) BN_free(local_n); return ret; }
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; BN_init(&f); BN_init(&ret); if ((ctx=BN_CTX_new()) == NULL) goto err; num=BN_num_bytes(rsa->n); if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL) { 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->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC)) { BN_MONT_CTX* bn_mont_ctx; if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL) goto err; if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx)) { BN_MONT_CTX_free(bn_mont_ctx); goto err; } if (rsa->_method_mod_n == NULL) /* other thread may have finished first */ { CRYPTO_w_lock(CRYPTO_LOCK_RSA); if (rsa->_method_mod_n == NULL) { rsa->_method_mod_n = bn_mont_ctx; bn_mont_ctx = NULL; } CRYPTO_w_unlock(CRYPTO_LOCK_RSA); } if (bn_mont_ctx) BN_MONT_CTX_free(bn_mont_ctx); } 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_free(ctx); BN_clear_free(&f); BN_clear_free(&ret); if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
static int RSA_null_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); return -1; }
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); }
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 local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; 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)) goto err; if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } 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); }
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 = 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) { 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); 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: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { OPENSSL_cleanse(s, (unsigned int)siglen); free(s); } return ret; }
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; if (rctx->md) { if (tbslen != (size_t)EVP_MD_size(rctx->md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } if (EVP_MD_type(rctx->md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_X931_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; memcpy(rctx->tbuf, tbs, tbslen); rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md, rctx->mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); } else return -1; } else ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, rctx->pad_mode); if (ret < 0) return ret; *siglen = ret; return 1; }
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = ctx->data; switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: if (p1 >= RSA_PKCS1_PADDING && p1 <= RSA_PKCS1_PSS_PADDING) { if (!check_padding_md(rctx->md, p1)) return 0; if (p1 == RSA_PKCS1_PSS_PADDING) { if (!(ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } if (p1 == RSA_PKCS1_OAEP_PADDING) { if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; } bad_pad: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_GET_RSA_PADDING: *(int *)p2 = rctx->pad_mode; return 1; case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) *(int *)p2 = rctx->saltlen; else { if (p1 < -2) return -2; rctx->saltlen = p1; } return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); return -2; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) return -2; rctx->pub_exp = p2; return 1; case EVP_PKEY_CTRL_MD: if (!check_padding_md(p2, rctx->pad_mode)) return 0; rctx->md = p2; return 1; case EVP_PKEY_CTRL_RSA_MGF1_MD: case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { if (rctx->mgf1md) *(const EVP_MD **)p2 = rctx->mgf1md; else *(const EVP_MD **)p2 = rctx->md; } else rctx->mgf1md = p2; return 1; case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_DECRYPT: { X509_ALGOR *alg = NULL; ASN1_OBJECT *encalg = NULL; if (p2) CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg); if (alg) X509_ALGOR_get0(&encalg, NULL, NULL, alg); if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep) rctx->pad_mode = RSA_PKCS1_OAEP_PADDING; } /* FALLTHROUGH */ case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_SIGN: return 1; #endif case EVP_PKEY_CTRL_PEER_KEY: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; } }
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { long lval; char *ep; if (!value) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); return 0; } if (!strcmp(type, "rsa_padding_mode")) { int pm; if (!strcmp(value, "pkcs1")) pm = RSA_PKCS1_PADDING; else if (!strcmp(value, "sslv23")) pm = RSA_SSLV23_PADDING; else if (!strcmp(value, "none")) pm = RSA_NO_PADDING; else if (!strcmp(value, "oeap")) pm = RSA_PKCS1_OAEP_PADDING; else if (!strcmp(value, "oaep")) pm = RSA_PKCS1_OAEP_PADDING; else if (!strcmp(value, "x931")) pm = RSA_X931_PADDING; else if (!strcmp(value, "pss")) pm = RSA_PKCS1_PSS_PADDING; else { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); return -2; } return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); } if (!strcmp(type, "rsa_pss_saltlen")) { int saltlen; errno = 0; lval = strtol(value, &ep, 10); if (value[0] == '\0' || *ep != '\0') goto not_a_number; if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || (lval > INT_MAX || lval < INT_MIN)) goto out_of_range; saltlen = lval; return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); } if (!strcmp(type, "rsa_keygen_bits")) { int nbits; errno = 0; lval = strtol(value, &ep, 10); if (value[0] == '\0' || *ep != '\0') goto not_a_number; if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || (lval > INT_MAX || lval < INT_MIN)) goto out_of_range; nbits = lval; return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); } if (!strcmp(type, "rsa_keygen_pubexp")) { int ret; BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) return 0; ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); if (ret <= 0) BN_free(pubexp); return ret; } not_a_number: out_of_range: return -2; }
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy; BIGNUM dmp1, dmq1, c, pr1; int ret = 0; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (r1 == NULL || m1 == NULL || vrfy == NULL) { RSAerr(RSA_F_RSA_EAY_MOD_EXP, ERR_R_MALLOC_FAILURE); goto err; } { BIGNUM p, q; /* * Make sure BN_mod_inverse in Montgomery intialization uses the * BN_FLG_CONSTTIME flag */ BN_init(&p); BN_init(&q); BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME); BN_with_flags(&q, rsa->q, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, &p, ctx) || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, &q, ctx)) { 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; /* compute I mod q */ BN_init(&c); BN_with_flags(&c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, &c, rsa->q, ctx)) goto err; /* compute r1^dmq1 mod q */ BN_init(&dmq1); BN_with_flags(&dmq1, rsa->dmq1, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(m1, r1, &dmq1, rsa->q, ctx, rsa->_method_mod_q)) goto err; /* compute I mod p */ BN_with_flags(&c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, &c, rsa->p, ctx)) goto err; /* compute r1^dmp1 mod p */ BN_init(&dmp1); BN_with_flags(&dmp1, rsa->dmp1, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, r1, &dmp1, rsa->p, ctx, rsa->_method_mod_p)) goto err; if (!BN_sub(r0, r0, m1)) goto err; /* * This will help stop the size of r0 increasing, which does * affect the multiply if it optimised for a power of 2 size */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; /* Turn BN_FLG_CONSTTIME flag on before division operation */ BN_init(&pr1); BN_with_flags(&pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, &pr1, rsa->p, ctx)) goto err; /* * If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->q, ctx)) goto err; if (!BN_add(r0, r1, m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; /* * If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* * 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM d; BN_init(&d); BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, I, &d, rsa->n, ctx, rsa->_method_mod_n)) { goto err; } } } ret = 1; err: BN_CTX_end(ctx); return ret; }
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, const unsigned char *from, int flen, int num) { int i; /* |em| is the encoded message, zero-padded to exactly |num| bytes */ unsigned char *em = NULL; unsigned int good, found_zero_byte; int zero_index = 0, msg_index, mlen = -1; if (tlen < 0 || flen < 0) return -1; /* * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", * section 7.2.2. */ if (flen > num) goto err; if (num < 11) goto err; em = OPENSSL_malloc(num); if (em == NULL) { RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); return -1; } memset(em, 0, num); /* * Always do this zero-padding copy (even when num == flen) to avoid * leaking that information. The copy still leaks some side-channel * information, but it's impossible to have a fixed memory access * pattern since we can't read out of the bounds of |from|. * * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. */ memcpy(em + num - flen, from, flen); good = constant_time_is_zero(em[0]); good &= constant_time_eq(em[1], 2); found_zero_byte = 0; for (i = 2; i < num; i++) { unsigned int equals0 = constant_time_is_zero(em[i]); zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index); found_zero_byte |= equals0; } /* * PS must be at least 8 bytes long, and it starts two bytes into |em|. * If we never found a 0-byte, then |zero_index| is 0 and the check * also fails. */ good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); /* * Skip the zero byte. This is incorrect if we never found a zero-byte * but in this case we also do not copy the message out. */ msg_index = zero_index + 1; mlen = num - msg_index; /* * For good measure, do this check in constant time as well; it could * leak something if |tlen| was assuming valid padding. */ good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); /* * We can't continue in constant-time because we need to copy the result * and we cannot fake its length. This unavoidably leaks timing * information at the API boundary. * TODO(emilia): this could be addressed at the call site, * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. */ if (!good) { mlen = -1; goto err; } memcpy(to, em + msg_index, mlen); err: if (em != NULL) OPENSSL_free(em); if (mlen == -1) RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); return mlen; }
int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; int ret = 1, ex_primes = 0, idx; RSA_PRIME_INFO *pinfo; if (key->p == NULL || key->q == NULL || key->n == NULL || key->e == NULL || key->d == NULL) { RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING); return 0; } /* multi-prime? */ if (key->version == RSA_ASN1_VERSION_MULTI) { ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos); if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) { RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY); return 0; } } i = BN_new(); j = BN_new(); k = BN_new(); l = BN_new(); m = BN_new(); ctx = BN_CTX_new(); if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE); goto err; } if (BN_is_one(key->e)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); } if (!BN_is_odd(key->e)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); } /* p prime? */ if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME); } /* q prime? */ if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME); } /* r_i prime? */ for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME); } } /* n = p*q * r_3...r_i? */ if (!BN_mul(i, key->p, key->q, ctx)) { ret = -1; goto err; } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (!BN_mul(i, i, pinfo->r, ctx)) { ret = -1; goto err; } } if (BN_cmp(i, key->n) != 0) { ret = 0; if (ex_primes) RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); else RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod \lambda(n)? */ if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } if (!BN_sub(j, key->q, BN_value_one())) { ret = -1; goto err; } /* now compute k = \lambda(n) = LCM(i, j, r_3 - 1...) */ if (!BN_mul(l, i, j, ctx)) { ret = -1; goto err; } if (!BN_gcd(m, i, j, ctx)) { ret = -1; goto err; } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (!BN_sub(k, pinfo->r, BN_value_one())) { ret = -1; goto err; } if (!BN_mul(l, l, k, ctx)) { ret = -1; goto err; } if (!BN_gcd(m, m, k, ctx)) { ret = -1; goto err; } } if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ ret = -1; goto err; } if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { ret = -1; goto err; } if (!BN_is_one(i)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1); } if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { /* dmp1 = d mod (p-1)? */ if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, key->dmp1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ if (!BN_sub(i, key->q, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, key->dmq1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); } /* iqmp = q^-1 mod p? */ if (!BN_mod_inverse(i, key->q, key->p, ctx)) { ret = -1; goto err; } if (BN_cmp(i, key->iqmp) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q); } } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); /* d_i = d mod (r_i - 1)? */ if (!BN_sub(i, pinfo->r, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, pinfo->d) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); } /* t_i = R_i ^ -1 mod r_i ? */ if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) { ret = -1; goto err; } if (BN_cmp(i, pinfo->t) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); } } err: BN_free(i); BN_free(j); BN_free(k); BN_free(l); BN_free(m); BN_CTX_free(ctx); return ret; }
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; #ifdef OPENSSL_FIPS if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); return 0; } #endif 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=(unsigned char *)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) { 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) { if (((dtype == NID_md5) && (sigtype == NID_md5WithRSAEncryption)) || ((dtype == NID_md2) && (sigtype == NID_md2WithRSAEncryption))) { /* ok, we will let it through */ #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) fprintf(stderr,"signature has problems, re-make with post SSLeay045\n"); #endif } else { 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: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); } return(ret); }
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = ctx->data; switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { if (!check_padding_md(rctx->md, p1)) return 0; if (p1 == RSA_PKCS1_PSS_PADDING) { if (!(ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } if (p1 == RSA_PKCS1_OAEP_PADDING) { if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; } bad_pad: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_GET_RSA_PADDING: *(int *)p2 = rctx->pad_mode; return 1; case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) *(int *)p2 = rctx->saltlen; else { if (p1 < -2) return -2; rctx->saltlen = p1; } return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); return -2; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) return -2; BN_free(rctx->pub_exp); rctx->pub_exp = p2; return 1; case EVP_PKEY_CTRL_RSA_OAEP_MD: case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) *(const EVP_MD **)p2 = rctx->md; else rctx->md = p2; return 1; case EVP_PKEY_CTRL_MD: if (!check_padding_md(p2, rctx->pad_mode)) return 0; rctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = rctx->md; return 1; case EVP_PKEY_CTRL_RSA_MGF1_MD: case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { if (rctx->mgf1md) *(const EVP_MD **)p2 = rctx->mgf1md; else *(const EVP_MD **)p2 = rctx->md; } else rctx->mgf1md = p2; return 1; case EVP_PKEY_CTRL_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } if (rctx->oaep_label) OPENSSL_free(rctx->oaep_label); if (p2 && p1 > 0) { rctx->oaep_label = p2; rctx->oaep_labellen = p1; } else { rctx->oaep_label = NULL; rctx->oaep_labellen = 0; } return 1; case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } *(unsigned char **)p2 = rctx->oaep_label; return rctx->oaep_labellen; case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_DECRYPT: case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_SIGN: return 1; #endif case EVP_PKEY_CTRL_PEER_KEY: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; } }
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; #ifdef OPENSSL_FIPS if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); return 0; } #endif 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 (sig.algor->algorithm->length == 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=(unsigned char *)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_cleanse(tmps,(unsigned int)j+1); OPENSSL_free(tmps); } return(ret); }
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { if (!value) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); return 0; } if (!strcmp(type, "rsa_padding_mode")) { int pm; if (!strcmp(value, "pkcs1")) pm = RSA_PKCS1_PADDING; else if (!strcmp(value, "sslv23")) pm = RSA_SSLV23_PADDING; else if (!strcmp(value, "none")) pm = RSA_NO_PADDING; else if (!strcmp(value, "oeap")) pm = RSA_PKCS1_OAEP_PADDING; else if (!strcmp(value, "oaep")) pm = RSA_PKCS1_OAEP_PADDING; else if (!strcmp(value, "x931")) pm = RSA_X931_PADDING; else if (!strcmp(value, "pss")) pm = RSA_PKCS1_PSS_PADDING; else { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); return -2; } return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); } if (!strcmp(type, "rsa_pss_saltlen")) { int saltlen; saltlen = atoi(value); return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); } if (!strcmp(type, "rsa_keygen_bits")) { int nbits; nbits = atoi(value); return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); } if (!strcmp(type, "rsa_keygen_pubexp")) { int ret; BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) return 0; ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); if (ret <= 0) BN_free(pubexp); return ret; } if (!strcmp(type, "rsa_mgf1_md")) { const EVP_MD *md; if (!(md = EVP_get_digestbyname(value))) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); } if (!strcmp(type, "rsa_oaep_md")) { const EVP_MD *md; if (!(md = EVP_get_digestbyname(value))) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); } if (!strcmp(type, "rsa_oaep_label")) { unsigned char *lab; long lablen; int ret; lab = string_to_hex(value, &lablen); if (!lab) return 0; ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); if (ret <= 0) OPENSSL_free(lab); return ret; } return -2; }
/* 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 local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { BN_init(&local_d); d = &local_d; 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)) goto err; if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } 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)) 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); }
/* 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; }
/* 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) && ((ret->d[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); }
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; }
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; BIGNUM local_r0, local_d, local_p; BIGNUM *pr0, *d, *p; int bitsp, bitsq, ok = -1, n = 0; BN_CTX *ctx = NULL; ctx = BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; bitsp = (bits + 1) / 2; bitsq = bits - bitsp; /* We need the RSA components non-NULL */ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) goto err; if (!rsa->d && ((rsa->d = BN_new()) == NULL)) goto err; if (!rsa->e && ((rsa->e = BN_new()) == NULL)) goto err; if (!rsa->p && ((rsa->p = BN_new()) == NULL)) goto err; if (!rsa->q && ((rsa->q = BN_new()) == NULL)) goto err; if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) goto err; if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) goto err; if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q */ for (;;) { if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2, rsa->p, BN_value_one())) goto err; if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; if (BN_is_one(r1)) break; if (!BN_GENCB_call(cb, 2, n++)) goto err; } if (!BN_GENCB_call(cb, 3, 0)) goto err; for (;;) { /* * When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for this and * bail if it happens 3 times. */ unsigned int degenerate = 0; do { if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) goto err; } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if (degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2, rsa->q, BN_value_one())) goto err; if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; if (BN_is_one(r1)) break; if (!BN_GENCB_call(cb, 2, n++)) goto err; } if (!BN_GENCB_call(cb, 3, 1)) goto err; if (BN_cmp(rsa->p, rsa->q) < 0) { tmp = rsa->p; rsa->p = rsa->q; rsa->q = tmp; } /* calculate n */ if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) goto err; /* calculate d */ if (!BN_sub(r1, rsa->p, BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2, rsa->q, BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0, r1, r2, ctx)) goto err; /* (p-1)(q-1) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1, d, r1, ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1, d, r2, ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) goto err; ok = 1; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); ok = 0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int i, 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; /* * BN_bn2binpad puts in leading 0 bytes if the number is less than * the length of the modulus. */ r = BN_bn2binpad(ret, to, num); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return r; }
static int RSA_null_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); return -1; }
int RSA_check_key (const RSA * key) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; int r; int ret = 1; if (!key->p || !key->q || !key->n || !key->e || !key->d) { RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING); return 0; } i = BN_new (); j = BN_new (); k = BN_new (); l = BN_new (); m = BN_new (); ctx = BN_CTX_new (); if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; RSAerr (RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); goto err; } /* p prime? */ r = BN_is_prime_ex (key->p, BN_prime_checks, NULL, NULL); if (r != 1) { ret = r; if (r != 0) goto err; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); } /* q prime? */ r = BN_is_prime_ex (key->q, BN_prime_checks, NULL, NULL); if (r != 1) { ret = r; if (r != 0) goto err; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); } /* n = p*q? */ r = BN_mul (i, key->p, key->q, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp (i, key->n) != 0) { ret = 0; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod lcm(p-1,q-1)? */ r = BN_sub (i, key->p, BN_value_one ()); if (!r) { ret = -1; goto err; } r = BN_sub (j, key->q, BN_value_one ()); if (!r) { ret = -1; goto err; } /* now compute k = lcm(i,j) */ r = BN_mul (l, i, j, ctx); if (!r) { ret = -1; goto err; } r = BN_gcd (m, i, j, ctx); if (!r) { ret = -1; goto err; } r = BN_div (k, NULL, l, m, ctx); /* remainder is 0 */ if (!r) { ret = -1; goto err; } r = BN_mod_mul (i, key->d, key->e, k, ctx); if (!r) { ret = -1; goto err; } if (!BN_is_one (i)) { ret = 0; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); } if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { /* dmp1 = d mod (p-1)? */ r = BN_sub (i, key->p, BN_value_one ()); if (!r) { ret = -1; goto err; } r = BN_mod (j, key->d, i, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp (j, key->dmp1) != 0) { ret = 0; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ r = BN_sub (i, key->q, BN_value_one ()); if (!r) { ret = -1; goto err; } r = BN_mod (j, key->d, i, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp (j, key->dmq1) != 0) { ret = 0; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); } /* iqmp = q^-1 mod p? */ if (!BN_mod_inverse (i, key->q, key->p, ctx)) { ret = -1; goto err; } if (BN_cmp (i, key->iqmp) != 0) { ret = 0; RSAerr (RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); } } err: if (i != NULL) BN_free (i); if (j != NULL) BN_free (j); if (k != NULL) BN_free (k); if (l != NULL) BN_free (l); if (m != NULL) BN_free (m); if (ctx != NULL) BN_CTX_free (ctx); return (ret); }
int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, const EVP_MD *Hash, const unsigned char *EM, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; const unsigned char *H; unsigned char *DB = NULL; EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; hLen = EVP_MD_size(Hash); if (hLen < 0) goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is autorecovered from signature * -N reserved */ if (sLen == -1) sLen = hLen; else if (sLen == -2) sLen = -2; else if (sLen < -2) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID); goto err; } if (MSBits == 0) { EM++; emLen--; } if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */ { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE); goto err; } if (EM[emLen - 1] != 0xbc) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID); goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; DB = (unsigned char*)OPENSSL_malloc(maskedDBLen); if (!DB) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0) goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) DB[0] &= 0xFF >> (8 - MSBits); for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ; if (DB[i++] != 0x1) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED); goto err; } if (sLen >= 0 && (maskedDBLen - i) != sLen) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED); goto err; } EVP_MD_CTX_init(&ctx); EVP_DigestInit_ex(&ctx, Hash, NULL); EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes); EVP_DigestUpdate(&ctx, mHash, hLen); if (maskedDBLen - i) EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i); EVP_DigestFinal(&ctx, H_, NULL); EVP_MD_CTX_cleanup(&ctx); if (TINYCLR_SSL_MEMCMP(H_, H, hLen)) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE); ret = 0; } else ret = 1; err: if (DB) OPENSSL_free(DB); return ret; }
RSA *RSA_new_method(ENGINE *engine) { RSA *ret; ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); if (ret == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); return NULL; } ret->meth = RSA_get_default_method(); #ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); OPENSSL_free(ret); return NULL; } ret->engine = engine; } else ret->engine = ENGINE_get_default_RSA(); if(ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if(!ret->meth) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); ENGINE_finish(ret->engine); OPENSSL_free(ret); return NULL; } } #endif #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) { RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD); #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif OPENSSL_free(ret); return NULL; } #endif ret->pad=0; ret->version=0; ret->n=NULL; ret->e=NULL; ret->d=NULL; ret->p=NULL; ret->q=NULL; ret->dmp1=NULL; ret->dmq1=NULL; ret->iqmp=NULL; ret->references=1; ret->_method_mod_n=NULL; ret->_method_mod_p=NULL; ret->_method_mod_q=NULL; ret->blinding=NULL; ret->mt_blinding=NULL; ret->bignum_data=NULL; ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif OPENSSL_free(ret); return(NULL); } if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; } return(ret); }
/* sign arbitrary data */ static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; HCRYPTHASH hash; DWORD hash_size, len, i; unsigned char *buf; if (cd == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (padding != RSA_PKCS1_PADDING) { /* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); return 0; } /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would * be way to straightforward for M$, I guess... So we have to do it this * tricky way instead, by creating a "Hash", and load the already-made hash * from 'from' into it. */ /* For now, we only support NID_md5_sha1 */ if (flen != SSL_SIG_LENGTH) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) { CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_CREATE_HASH); return 0; } len = sizeof(hash_size); if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 0)) { CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_GET_HASH_PARAM); CryptDestroyHash(hash); return 0; } if ((int) hash_size != flen) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); CryptDestroyHash(hash); return 0; } if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SET_HASH_PARAM); CryptDestroyHash(hash); return 0; } len = RSA_size(rsa); buf = malloc(len); if (buf == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); CryptDestroyHash(hash); return 0; } if (!CryptSignHash(hash, cd->key_spec, NULL, 0, buf, &len)) { CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SIGN_HASH); CryptDestroyHash(hash); free(buf); return 0; } /* and now, we have to reverse the byte-order in the result from CryptSignHash()... */ for (i = 0; i < len; i++) to[i] = buf[len - i - 1]; free(buf); CryptDestroyHash(hash); return len; }
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = ctx->data; switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { if (!check_padding_md(rctx->md, p1)) return 0; if (p1 == RSA_PKCS1_PSS_PADDING) { if (!(ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } if (p1 == RSA_PKCS1_OAEP_PADDING) { if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; } bad_pad: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: if (p1 < -2) return -2; if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); return -2; } rctx->saltlen = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); return -2; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) return -2; rctx->pub_exp = p2; return 1; case EVP_PKEY_CTRL_MD: if (!check_padding_md(p2, rctx->pad_mode)) return 0; rctx->md = p2; return 1; case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_DECRYPT: case EVP_PKEY_CTRL_CMS_SIGN: #endif return 1; case EVP_PKEY_CTRL_PEER_KEY: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; } }