/* 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;

/* blinding structure 共享时使用。 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);
}

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);
}

/* 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);

代码解析:

1. BIGNUM *f , *ret ;

bignum  --->   typedef struct bignum_st BIGNUM;  -----> struct bignum_st

{

BN_ULONG  *d;

int  top;

int  dmax;

int  neg;

int  flags;

}

各项意义如下:

d: BN_ULONG,数组指针首地址,大数就存放在这里面,不过是倒放的。比如,用户要存放的

大数为12345678000(通过BN_bin2bn放入),则d的内容如下:

0x300x30 0x30 0x38 0x37 0x36 0x35 0x34 0x33 0x32 0x31;

top:用来指明大数占多少个BN_ULONG空间,上例中top为3。

dmax:d数组的大小。

neg:是否为负数,如果为1,则是负数,为0,则为正数。

flags:用于存放一些标记,比如flags含有BN_FLG_STATIC_DATA时,表明d的内存是静态分配的;

含有BN_FLG_MALLOCED时,d的内存是动态分配的。

2. BN_CTX *ctx = NULL;   ---------》  typedef struct bignum_ctx BN_CTX;   ------->    struct  bignum_ctx

{

BN_POOL pool; //大数句柄

BN_STACK  stack; //堆栈帧

unsigned int  used; //分配的大数

int  err_stack; //

int  too_many;

}

typedef struct bignum_pool

{

BN_POOL_ITEM  *head, *current,  *tail; // BN_POOL_ITEM ---> typedef  struct bignum_bool;

unsigned  used, size;

}

typedef  struct bignum_ctx_stack

{

unsigned int *indexes;

unsigned int depth, size;

} BN_STACK;

rsa_eay_private_encrypt相关推荐

  1. 《openssl 编程》之 RSA(转)

    17.1  RSA介绍 RSA算法是一个广泛使用的公钥算法.其密钥包括公钥和私钥.它能用于数字签名.身份认证以及密钥交换.RSA密钥长度一般使用1024位或者更高.RSA密钥信息主要包括[1]: Ø  ...

  2. CSP应用开发-CryptAPI函数库介绍

    基本加密函数为开发加密应用程序提供了足够灵活的空间.所有CSP的通讯都是通过这些函数.一个CSP是实现所有加密操作的独立模块.在每一个应用程序中至少需要提供一个CSP来完成所需的加密操作.如果使用多于 ...

  3. 17.openssl编程——RSA介绍

    17.1  RSA介绍 RSA算法是一个广泛使用的公钥算法.器密钥包括公钥和私钥.他能用于数字签名.身份认证以及密钥交换.RSA密钥信息主要包括: * n:模数 * e:公钥指数 * d:私钥指数 * ...

  4. openssl之RSA相关函数

    Ref URL: http://blog.sina.com.cn/s/blog_4f51dac40100u2jt.html 主要介绍了openssl之RSA相关函数,这个对学习和实现RSA算法比较有帮 ...

最新文章

  1. pytorch one-hot转数组
  2. 港口物流系统设计与优化-SMU在线学习笔记
  3. python练习题:使用循环和函数实现一个摇骰子小游戏
  4. 从零构建vue+webpack (一)
  5. 使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处
  6. 基于.NET CORE微服务框架 -谈谈Cache中间件和缓存降级
  7. Smack 3.3.1 发布,Java 的 XMPP 开发包
  8. Destroying The Graph 最小点权集--最小割--最大流
  9. Java程序员从笨鸟到菜鸟之(八十七)跟我学jquery(三)jquery动态创建元素和常用函数示例...
  10. Android lollipop 更新问题
  11. 杭州爱华科技“AWA5661”噪音采集软件
  12. 分享一下我在东方时尚学车的经历
  13. JSON校验和JSON在线编辑器
  14. STM32程序下载2:通过STM32CubePro-ST-Link下载
  15. Flash数据读取和保存
  16. vue-element-admin安装指南
  17. bzoj 1491: [NOI2007]社交网络
  18. Failed to get convolution algorithm. This is probably because cuDNN failed to initialize,
  19. java计算机毕业设计体育新闻网站源码+系统+数据库+lw文档+mybatis+运行部署
  20. Do Deep Neural Networks Learn Facial Action Units When Doing Expression Recognition?阅读笔记

热门文章

  1. 国际服务贸易期末考试复习资料
  2. matlab simulink仿真实现电力电子的整流电路
  3. 上海租房。20160420
  4. Python中shape简易用法
  5. 小郡肝火锅点餐系统——测试部署发布
  6. LabVIEW编程LabVIEW开发在LabVIEW中复用现有代码
  7. Visual Studio Installer 一直提取文件0B不动怎么办:修改DNS教程
  8. 小米笔记本触摸板失效
  9. 修改计算机照片格式怎么修,电脑上如何修改照片文件大小?2种免费方法简单解决...
  10. ios swift5 父子控制器