int BN_dec2bn(BIGNUM **bn, const char *a) { BIGNUM *ret=NULL; BN_ULONG l=0; int neg=0,i,j; int num; if ((a == NULL) || (*a == '\0')) return(0); if (*a == '-') { neg=1; a++; } for (i=0; isdigit((unsigned char) a[i]); i++) ; num=i+neg; if (bn == NULL) return(num); /* a is the start of the digits, and it is 'i' long. * We chop it into BN_DEC_NUM digits at a time */ if (*bn == NULL) { if ((ret=BN_new()) == NULL) return(0); } else { ret= *bn; BN_zero(ret); } /* i is the number of digests, a bit of an over expand; */ if (bn_expand(ret,i*4) == NULL) goto err; j=BN_DEC_NUM-(i%BN_DEC_NUM); if (j == BN_DEC_NUM) j=0; l=0; while (*a) { l*=10; l+= *a-'0'; a++; if (++j == BN_DEC_NUM) { BN_mul_word(ret,BN_DEC_CONV); BN_add_word(ret,l); l=0; j=0; } } ret->neg=neg; bn_correct_top(ret); *bn=ret; bn_check_top(ret); return(num); err: if (*bn == NULL) BN_free(ret); return(0); }
int BN_set_word(BIGNUM *a, BN_ULONG w) { bn_check_top(a); if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0); a->neg = 0; a->d[0] = w; a->top = (w ? 1 : 0); bn_check_top(a); return(1); }
static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *i, RSA *rsa ) { CHEESE () ; if ( !zencod_dso ) { ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_NOT_LOADED); return 0; } if ( !rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp ) { ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BAD_KEY_COMPONENTS); return 0; } /* Do in software if argument is too large for hardware */ if ( RSA_size(rsa) * 8 > ZENBRIDGE_MAX_KEYSIZE_RSA_CRT ) { const RSA_METHOD *meth; meth = RSA_PKCS1_SSLeay(); return meth->rsa_mod_exp(r0, i, rsa); } else { zen_nb_t y, x, p, q, dmp1, dmq1, iqmp; if ( !bn_expand(r0, RSA_size(rsa) * 8) ) { ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BN_EXPAND_FAIL); return 0; } r0->top = (RSA_size(rsa) * 8 + BN_BITS2 - 1) / BN_BITS2; BIGNUM2ZEN ( &x, i ) ; BIGNUM2ZEN ( &y, r0 ) ; BIGNUM2ZEN ( &p, rsa->p ) ; BIGNUM2ZEN ( &q, rsa->q ) ; BIGNUM2ZEN ( &dmp1, rsa->dmp1 ) ; BIGNUM2ZEN ( &dmq1, rsa->dmq1 ) ; BIGNUM2ZEN ( &iqmp, rsa->iqmp ) ; if ( ptr_zencod_rsa_mod_exp_crt ( &y, &x, &p, &q, &dmp1, &dmq1, &iqmp ) < 0 ) { PERROR("zenbridge_rsa_mod_exp_crt"); ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_REQUEST_FAILED); return 0; } return 1; } }
/* This function is aliased to RSA_mod_exp (with the mont stuff dropped). */ static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx ) { CHEESE () ; if ( !zencod_dso ) { ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_NOT_LOADED); return 0; } /* Do in software if argument is too large for hardware */ if ( BN_num_bits(m) > ZENBRIDGE_MAX_KEYSIZE_RSA ) { const RSA_METHOD *meth; meth = RSA_PKCS1_SSLeay(); return meth->bn_mod_exp(r, a, p, m, ctx, m_ctx); } else { zen_nb_t y, x, e, n; if ( !bn_expand(r, BN_num_bits(m)) ) { ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL); return 0; } r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; BIGNUM2ZEN ( &x, a ) ; BIGNUM2ZEN ( &y, r ) ; BIGNUM2ZEN ( &e, p ) ; BIGNUM2ZEN ( &n, m ) ; if ( ptr_zencod_rsa_mod_exp ( &y, &x, &n, &e ) < 0 ) { PERROR("zenbridge_rsa_mod_exp"); ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_REQUEST_FAILED); return 0; } return 1; } }
/*Turn an AEP Big Num back to a user big num*/ static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum) { BIGNUM* bn; #ifndef SIXTY_FOUR_BIT_LONG int i; #endif bn = (BIGNUM*)ArbBigNum; /*Expand the result bn so that it can hold our big num. Size is in bits*/ bn_expand(bn, (int)(BigNumSize << 3)); #ifdef SIXTY_FOUR_BIT_LONG bn->top = BigNumSize >> 3; if((BigNumSize & 7) != 0) bn->top++; memset(bn->d, 0, bn->top << 3); memcpy(bn->d, AEP_BigNum, BigNumSize); #else bn->top = BigNumSize >> 2; for(i=0;i<bn->top;i++) { bn->d[i] = (AEP_U32) ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 | ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]); AEP_BigNum += 4; } #endif return AEP_R_OK; }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int ret = 0; BIGNUM *Ri, *R; BN_CTX_start(ctx); if ((Ri = BN_CTX_get(ctx)) == NULL) goto err; R = &(mont->RR); /* grab RR as a temp */ if (!BN_copy(&(mont->N), mod)) goto err; /* Set N */ mont->N.neg = 0; #ifdef MONT_WORD { BIGNUM tmod; BN_ULONG buf[2]; BN_init(&tmod); tmod.d = buf; tmod.dmax = 2; tmod.neg = 0; mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) /* Only certain BN_BITS2<=32 platforms actually make use of * n0[1], and we could use the #else case (with a shorter R * value) for the others. However, currently only the assembler * files do know which is which. */ BN_zero(R); if (!(BN_set_bit(R, 2 * BN_BITS2))) goto err; tmod.top = 0; if ((buf[0] = mod->d[0])) tmod.top = 1; if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) tmod.top = 2; if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) goto err; } else /* if N mod word size == 1 */ { if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) goto err; /* Ri-- (mod double word size) */ Ri->neg = 0; Ri->d[0] = BN_MASK2; Ri->d[1] = BN_MASK2; Ri->top = 2; } if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only couple of least significant words: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; #else BN_zero(R); if (!(BN_set_bit(R, BN_BITS2))) goto err; /* R */ buf[0] = mod->d[0]; /* tmod = N mod word size */ buf[1] = 0; tmod.top = buf[0] != 0 ? 1 : 0; /* Ri = R^-1 mod N*/ if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) goto err; } else /* if N mod word size == 1 */ { if (!BN_set_word(Ri, BN_MASK2)) goto err; /* Ri-- (mod word size) */ } if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only least significant word: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = 0; #endif } #else /* !MONT_WORD */ { /* bignum version */ mont->ri = BN_num_bits(&mont->N); BN_zero(R); if (!BN_set_bit(R, mont->ri)) goto err; /* R = 2^ri */ /* Ri = R^-1 mod N*/ if ((BN_mod_inverse_ct(Ri, R, &mont->N, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, mont->ri)) goto err; /* R*Ri */ if (!BN_sub_word(Ri, 1)) goto err; /* Ni = (R*Ri-1) / N */ if (!BN_div_ct(&(mont->Ni), NULL, Ri, &mont->N, ctx)) goto err; } #endif /* setup RR for conversions */ BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR), mont->ri*2)) goto err; if (!BN_mod_ct(&(mont->RR), &(mont->RR), &(mont->N), ctx)) goto err; ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int ret = 0; BIGNUM *Ri, *R; BIGNUM tmod; BN_ULONG buf[2]; if (BN_is_zero(mod)) { OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); return 0; } BN_CTX_start(ctx); Ri = BN_CTX_get(ctx); if (Ri == NULL) { goto err; } R = &mont->RR; /* grab RR as a temp */ if (!BN_copy(&mont->N, mod)) { goto err; /* Set N */ } mont->N.neg = 0; BN_init(&tmod); tmod.d = buf; tmod.dmax = 2; tmod.neg = 0; #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32) /* Only certain BN_BITS2<=32 platforms actually make use of * n0[1], and we could use the #else case (with a shorter R * value) for the others. However, currently only the assembler * files do know which is which. */ BN_zero(R); if (!BN_set_bit(R, 2 * BN_BITS2)) { goto err; } tmod.top = 0; if ((buf[0] = mod->d[0])) { tmod.top = 1; } if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) { tmod.top = 2; } if (BN_mod_inverse(Ri, R, &tmod, ctx) == NULL) { goto err; } if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) { goto err; /* R*Ri */ } if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) { goto err; } } else { /* if N mod word size == 1 */ if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) { goto err; } /* Ri-- (mod double word size) */ Ri->neg = 0; Ri->d[0] = BN_MASK2; Ri->d[1] = BN_MASK2; Ri->top = 2; } if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) { goto err; } /* Ni = (R*Ri-1)/N, * keep only couple of least significant words: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; #else BN_zero(R); if (!BN_set_bit(R, BN_BITS2)) { goto err; /* R */ } buf[0] = mod->d[0]; /* tmod = N mod word size */ buf[1] = 0; tmod.top = buf[0] != 0 ? 1 : 0; /* Ri = R^-1 mod N*/ if (BN_mod_inverse(Ri, R, &tmod, ctx) == NULL) { goto err; } if (!BN_lshift(Ri, Ri, BN_BITS2)) { goto err; /* R*Ri */ } if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) { goto err; } } else { /* if N mod word size == 1 */ if (!BN_set_word(Ri, BN_MASK2)) { goto err; /* Ri-- (mod word size) */ } } if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) { goto err; } /* Ni = (R*Ri-1)/N, * keep only least significant word: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = 0; #endif /* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */ int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR), ri * 2)) { goto err; } if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) { goto err; } ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_hex2bn(BIGNUM **bn, const char *a) { BIGNUM *ret=NULL; BN_ULONG l=0; int neg=0,h,m,i,j,k,c; int num; if ((a == NULL) || (*a == '\0')) return(0); if (*a == '-') { neg=1; a++; } for (i=0; isxdigit((unsigned char) a[i]); i++) ; num=i+neg; if (bn == NULL) return(num); /* a is the start of the hex digits, and it is 'i' long */ if (*bn == NULL) { if ((ret=BN_new()) == NULL) return(0); } else { ret= *bn; BN_zero(ret); } /* i is the number of hex digests; */ if (bn_expand(ret,i*4) == NULL) goto err; j=i; /* least significant 'hex' */ m=0; h=0; while (j > 0) { m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j; l=0; for (;;) { c=a[j-m]; if ((c >= '0') && (c <= '9')) k=c-'0'; else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10; else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10; else k=0; /* paranoia */ l=(l<<4)|k; if (--m <= 0) { ret->d[h++]=l; break; } } j-=(BN_BYTES*2); } ret->top=h; bn_correct_top(ret); ret->neg=neg; *bn=ret; bn_check_top(ret); return(num); err: if (*bn == NULL) BN_free(ret); return(0); }
/* DSA stuff Functions */ static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa ) { zen_nb_t p, q, g, x, y, r, s, data; DSA_SIG *sig; BIGNUM *bn_r = NULL; BIGNUM *bn_s = NULL; char msg[20]; CHEESE(); if ( !zencod_dso ) { ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_NOT_LOADED); goto FAILED; } if ( dlen > 160 ) { ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED); goto FAILED; } /* Do in software if argument is too large for hardware */ if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN || BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) { const DSA_METHOD *meth; ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS); meth = DSA_OpenSSL(); return meth->dsa_do_sign(dgst, dlen, dsa); } if ( !(bn_s = BN_new()) || !(bn_r = BN_new()) ) { ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS); goto FAILED; } if ( !bn_expand(bn_r, 160) || !bn_expand(bn_s, 160) ) { ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BN_EXPAND_FAIL); goto FAILED; } bn_r->top = bn_s->top = (160 + BN_BITS2 - 1) / BN_BITS2; BIGNUM2ZEN ( &p, dsa->p ) ; BIGNUM2ZEN ( &q, dsa->q ) ; BIGNUM2ZEN ( &g, dsa->g ) ; BIGNUM2ZEN ( &x, dsa->priv_key ) ; BIGNUM2ZEN ( &y, dsa->pub_key ) ; BIGNUM2ZEN ( &r, bn_r ) ; BIGNUM2ZEN ( &s, bn_s ) ; q.len = x.len = 160; ypcmem(msg, dgst, 20); ptr_zencod_init_number ( &data, 160, msg ) ; if ( ptr_zencod_dsa_do_sign ( 0, &data, &y, &p, &q, &g, &x, &r, &s ) < 0 ) { PERROR("zenbridge_dsa_do_sign"); ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED); goto FAILED; } if ( !( sig = DSA_SIG_new () ) ) { ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED); goto FAILED; } sig->r = bn_r; sig->s = bn_s; return sig; FAILED: if (bn_r) BN_free(bn_r); if (bn_s) BN_free(bn_s); return NULL; }