int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) { int ok = 0; BIGNUM *q = NULL; *ret = 0; q = BN_new(); if (q == NULL) goto err; BN_set_word(q, 1); if (BN_cmp(pub_key, q) <= 0) *ret |= DH_CHECK_PUBKEY_TOO_SMALL; BN_copy(q, dh->p); BN_sub_word(q, 1); if (BN_cmp(pub_key, q) >= 0) *ret |= DH_CHECK_PUBKEY_TOO_LARGE; ok = 1; err: if (q != NULL) BN_free(q); return (ok); }
static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { RSA *rsa = NULL; RSA_PKEY_CTX *rctx = ctx->data; if (!rctx->pub_exp) { rctx->pub_exp = BN_new(); if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) { return 0; } } rsa = RSA_new(); if (!rsa) { return 0; } if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { RSA_free(rsa); return 0; } EVP_PKEY_assign_RSA(pkey, rsa); return 1; }
EVP_PKEY *genKey() { EVP_PKEY *keypair = EVP_PKEY_new(); int keylen; char *pem_key; //BN_GENCB cb = { } BIGNUM *bne = BN_new(); RSA *rsa = RSA_new(); int ret; ret = BN_set_word( bne, kExp ); if( ret != 1 ) { BN_free( bne ); RSA_free( rsa ); EVP_PKEY_free( keypair ); return NULL; } RSA_generate_key_ex( rsa, kBits, bne, NULL ); EVP_PKEY_set1_RSA( keypair, rsa ); BN_free( bne ); RSA_free( rsa ); return keypair; }
/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>. * Return 0 on success, -1 on failure. */ int crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits) { if (env->key) RSA_free(env->key); { BIGNUM *e = BN_new(); RSA *r = NULL; if (!e) goto done; if (! BN_set_word(e, 65537)) goto done; r = RSA_new(); if (!r) goto done; if (RSA_generate_key_ex(r, bits, e, NULL) == -1) goto done; env->key = r; r = NULL; done: if (e) BN_clear_free(e); if (r) RSA_free(r); } if (!env->key) { sgx_puts("generate RSA key"); return -1; } return 0; }
int main(int argc, char const *argv[]) { RSA *rsa; int modulelen = 1024; int ret, i; unsigned int len; unsigned long e = RSA_3; BIGNUM *bn; unsigned char from[128]; unsigned char to[128]; bn = BN_new(); ret = BN_set_word(bn, e); rsa = RSA_new(); ret = RSA_generate_key_ex(rsa, modulelen, bn, NULL); if(ret != 1) { printf("ERROR in RSA_generate_key_ex\n"); goto finally; } for (i = 0; i < 100; ++i) { memset(&from[i], i, 1); /* code */ } ret = RSA_sign(NID_sha1, from ,100, to, &len, rsa); printf("ret = %d, len = %d\n", ret, len); ret = RSA_verify(NID_sha1, to, 100, from, len, rsa); printf("ret = %d, len = %d\n",ret, len ); finally: RSA_free(rsa); return 0; }
static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { RSA *rsa = NULL; RSA_PKEY_CTX *rctx = ctx->data; BN_GENCB *pcb; int ret; if (rctx->pub_exp == NULL) { rctx->pub_exp = BN_new(); if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) return 0; } rsa = RSA_new(); if (rsa == NULL) return 0; if (ctx->pkey_gencb) { pcb = BN_GENCB_new(); if (pcb == NULL) { RSA_free(rsa); return 0; } evp_pkey_set_cb_translate(pcb, ctx); } else { pcb = NULL; } ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); BN_GENCB_free(pcb); if (ret > 0 && !rsa_set_pss_param(rsa, ctx)) { RSA_free(rsa); return 0; } if (ret > 0) EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa); else RSA_free(rsa); return ret; }
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) { int ok = 0; BIGNUM *tmp = NULL; BN_CTX *ctx = NULL; *ret = 0; ctx = BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); if (tmp == NULL || !BN_set_word(tmp, 1)) goto err; if (BN_cmp(pub_key, tmp) <= 0) *ret |= DH_CHECK_PUBKEY_TOO_SMALL; if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) goto err; if (BN_cmp(pub_key, tmp) >= 0) *ret |= DH_CHECK_PUBKEY_TOO_LARGE; if (dh->q != NULL) { /* Check pub_key^q == 1 mod p */ if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) goto err; if (!BN_is_one(tmp)) *ret |= DH_CHECK_PUBKEY_INVALID; } ok = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return (ok); }
static void push_scale(void) { struct number *n; struct value *value; u_int scale = 0; value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: scale = value->u.num->scale; break; case BCODE_STRING: break; } stack_free_value(value); n = new_number(); bn_check(BN_set_word(n->number, scale)); push_number(n); } }
/* Zeroize */ static int Zeroize() { RSA *key; BIGNUM *bn; unsigned char userkey[16] = { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; size_t i; int n; key = FIPS_rsa_new(); bn = BN_new(); if (!key || !bn) return 0; BN_set_word(bn, 65537); if (!RSA_generate_key_ex(key, 1024,bn,NULL)) return 0; BN_free(bn); n = BN_num_bytes(key->d); printf(" Generated %d byte RSA private key\n", n); printf("\tBN key before overwriting:\n"); do_bn_print(stdout, key->d); BN_rand(key->d,n*8,-1,0); printf("\tBN key after overwriting:\n"); do_bn_print(stdout, key->d); printf("\tchar buffer key before overwriting: \n\t\t"); for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); printf("\n"); RAND_bytes(userkey, sizeof userkey); printf("\tchar buffer key after overwriting: \n\t\t"); for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); printf("\n"); return 1; }
BIGNUM *BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; BIGNUM *ret=NULL; int sign; if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { return BN_mod_inverse_no_branch(in, a, n, ctx); } bn_check_top(a); bn_check_top(n); BN_CTX_start(ctx); A = BN_CTX_get(ctx); B = BN_CTX_get(ctx); X = BN_CTX_get(ctx); D = BN_CTX_get(ctx); M = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); T = BN_CTX_get(ctx); if (T == NULL) goto err; if (in == NULL) R=BN_new(); else R=in; if (R == NULL) goto err; BN_one(X); BN_zero(Y); if (BN_copy(B,a) == NULL) goto err; if (BN_copy(A,n) == NULL) goto err; A->neg = 0; if (B->neg || (BN_ucmp(B, A) >= 0)) { if (!BN_nnmod(B, B, A, ctx)) goto err; } sign = -1; /* From B = a mod |n|, A = |n| it follows that * * 0 <= B < A, * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). */ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { /* Binary inversion algorithm; requires odd modulus. * This is faster than the general algorithm if the modulus * is sufficiently small (about 400 .. 500 bits on 32-bit * sytems, but much more on 64-bit systems) */ int shift; while (!BN_is_zero(B)) { /* * 0 < B < |n|, * 0 < A <= |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|) */ /* Now divide B by the maximum possible power of two in the integers, * and divide X by the same value mod |n|. * When we're done, (1) still holds. */ shift = 0; while (!BN_is_bit_set(B, shift)) /* note that 0 < B */ { shift++; if (BN_is_odd(X)) { if (!BN_uadd(X, X, n)) goto err; } /* now X is even, so we can easily divide it by two */ if (!BN_rshift1(X, X)) goto err; } if (shift > 0) { if (!BN_rshift(B, B, shift)) goto err; } /* Same for A and Y. Afterwards, (2) still holds. */ shift = 0; while (!BN_is_bit_set(A, shift)) /* note that 0 < A */ { shift++; if (BN_is_odd(Y)) { if (!BN_uadd(Y, Y, n)) goto err; } /* now Y is even */ if (!BN_rshift1(Y, Y)) goto err; } if (shift > 0) { if (!BN_rshift(A, A, shift)) goto err; } /* We still have (1) and (2). * Both A and B are odd. * The following computations ensure that * * 0 <= B < |n|, * 0 < A < |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|), * * and that either A or B is even in the next iteration. */ if (BN_ucmp(B, A) >= 0) { /* -sign*(X + Y)*a == B - A (mod |n|) */ if (!BN_uadd(X, X, Y)) goto err; /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that * actually makes the algorithm slower */ if (!BN_usub(B, B, A)) goto err; } else { /* sign*(X + Y)*a == A - B (mod |n|) */ if (!BN_uadd(Y, Y, X)) goto err; /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */ if (!BN_usub(A, A, B)) goto err; } } } else { /* general inversion algorithm */ while (!BN_is_zero(B)) { BIGNUM *tmp; /* * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* (D, M) := (A/B, A%B) ... */ if (BN_num_bits(A) == BN_num_bits(B)) { if (!BN_one(D)) goto err; if (!BN_sub(M,A,B)) goto err; } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { /* A/B is 1, 2, or 3 */ if (!BN_lshift1(T,B)) goto err; if (BN_ucmp(A,T) < 0) { /* A < 2*B, so D=1 */ if (!BN_one(D)) goto err; if (!BN_sub(M,A,B)) goto err; } else { /* A >= 2*B, so D=2 or D=3 */ if (!BN_sub(M,A,T)) goto err; if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */ if (BN_ucmp(A,D) < 0) { /* A < 3*B, so D=2 */ if (!BN_set_word(D,2)) goto err; /* M (= A - 2*B) already has the correct value */ } else { /* only D=3 remains */ if (!BN_set_word(D,3)) goto err; /* currently M = A - 2*B, but we need M = A - 3*B */ if (!BN_sub(M,M,B)) goto err; } } } else { if (!BN_div(D,M,A,B,ctx)) goto err; } /* Now * A = D*B + M; * thus we have * (**) sign*Y*a == D*B + M (mod |n|). */ tmp=A; /* keep the BIGNUM object, the value does not matter */ /* (A, B) := (B, A mod B) ... */ A=B; B=M; /* ... so we have 0 <= B < A again */ /* Since the former M is now B and the former B is now A, * (**) translates into * sign*Y*a == D*A + B (mod |n|), * i.e. * sign*Y*a - D*A == B (mod |n|). * Similarly, (*) translates into * -sign*X*a == A (mod |n|). * * Thus, * sign*Y*a + D*sign*X*a == B (mod |n|), * i.e. * sign*(Y + D*X)*a == B (mod |n|). * * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). * Note that X and Y stay non-negative all the time. */ /* most of the time D is very small, so we can optimize tmp := D*X+Y */ if (BN_is_one(D)) { if (!BN_add(tmp,X,Y)) goto err; } else { if (BN_is_word(D,2)) { if (!BN_lshift1(tmp,X)) goto err; } else if (BN_is_word(D,4)) { if (!BN_lshift(tmp,X,2)) goto err; } else if (D->top == 1) { if (!BN_copy(tmp,X)) goto err; if (!BN_mul_word(tmp,D->d[0])) goto err; } else { if (!BN_mul(tmp,D,X,ctx)) goto err; } if (!BN_add(tmp,tmp,Y)) goto err; } M=Y; /* keep the BIGNUM object, the value does not matter */ Y=X; X=tmp; sign = -sign; } } /* * The while loop (Euclid's algorithm) ends when * A == gcd(a,n); * we have * sign*Y*a == A (mod |n|), * where Y is non-negative. */ if (sign < 0) { if (!BN_sub(Y,n,Y)) goto err; } /* Now Y*a == A (mod |n|). */ if (BN_is_one(A)) { /* Y*a == 1 (mod |n|) */ if (!Y->neg && BN_ucmp(Y,n) < 0) { if (!BN_copy(R,Y)) goto err; } else { if (!BN_nnmod(R,Y,n,ctx)) goto err; } } else { BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); goto err; } ret=R; err: if ((ret == NULL) && (in == NULL)) BN_free(R); BN_CTX_end(ctx); bn_check_top(ret); return(ret); }
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) { int i, first, len = 0, c, use_bn; char ftmp[24], *tmp = ftmp; int tmpsize = sizeof ftmp; const char *p; unsigned long l; BIGNUM *bl = NULL; if (num == 0) return (0); else if (num == -1) num = strlen(buf); p = buf; c = *(p++); num--; if ((c >= '0') && (c <= '2')) { first= c-'0'; } else { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); goto err; } if (num <= 0) { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); goto err; } c = *(p++); num--; for (;;) { if (num <= 0) break; if ((c != '.') && (c != ' ')) { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); goto err; } l = 0; use_bn = 0; for (;;) { if (num <= 0) break; num--; c = *(p++); if ((c == ' ') || (c == '.')) break; if ((c < '0') || (c > '9')) { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); goto err; } if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { use_bn = 1; if (!bl) bl = BN_new(); if (!bl || !BN_set_word(bl, l)) goto err; } if (use_bn) { if (!BN_mul_word(bl, 10L) || !BN_add_word(bl, c-'0')) goto err; } else l = l * 10L + (long)(c - '0'); } if (len == 0) { if ((first < 2) && (l >= 40)) { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE); goto err; } if (use_bn) { if (!BN_add_word(bl, first * 40)) goto err; } else l += (long)first * 40; } i = 0; if (use_bn) { int blsize; blsize = BN_num_bits(bl); blsize = (blsize + 6) / 7; if (blsize > tmpsize) { if (tmp != ftmp) free(tmp); tmpsize = blsize + 32; tmp = malloc(tmpsize); if (!tmp) goto err; } while (blsize--) tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); } else { for (;;) { tmp[i++] = (unsigned char)l & 0x7f; l >>= 7L; if (l == 0L) break; } } if (out != NULL) { if (len + i > olen) { ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); goto err; } while (--i > 0) out[len++] = tmp[i]|0x80; out[len++] = tmp[0]; } else len += i; } if (tmp != ftmp) free(tmp); BN_free(bl); return (len); err: if (tmp != ftmp) free(tmp); BN_free(bl); return (0); }
void BigNumber::SetDword(uint32 val) { BN_set_word(_bn, val); }
static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) { EC_GROUP *group = NULL; EC_POINT *P = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL; int ok = 0; int seed_len = 0; int param_len = 0; const unsigned char *params = NULL; ctx = BN_CTX_new(); if (ctx == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } seed_len = data->seed_len; param_len = data->param_len; params = (const unsigned char *)(data+1); /* skip header */ params += seed_len; /* skip seed */ if ( !(p = BN_bin2bn(params+0*param_len, param_len, NULL)) || !(a = BN_bin2bn(params+1*param_len, param_len, NULL)) || !(b = BN_bin2bn(params+2*param_len, param_len, NULL)) ) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if ((P = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if ( !(x = BN_bin2bn(params+3*param_len, param_len, NULL)) || !(y = BN_bin2bn(params+4*param_len, param_len, NULL)) ) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if ( !(order = BN_bin2bn(params+5*param_len, param_len, NULL)) || !BN_set_word(x, (BN_ULONG)data->cofactor) ) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_set_generator(group, P, order, x)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (seed_len) { if (!EC_GROUP_set_seed(group, params-seed_len, seed_len)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } ok = 1; err: if (!ok) { EC_GROUP_free(group); group = NULL; } if (P) { EC_POINT_free(P); } if (ctx) { BN_CTX_free(ctx); } if (p) { BN_free(p); } if (a) { BN_free(a); } if (b) { BN_free(b); } if (order) { BN_free(order);} if (x) { BN_free(x); } if (y) { BN_free(y); } return group; }
/* Actually there is no reason to insist that 'generator' be a generator. * It's just as OK (and in some sense better) to use a generator of the * order-q subgroup. */ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) { BIGNUM *t1,*t2; int g,ok= -1; BN_CTX *ctx=NULL; ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) goto err; /* Make sure 'ret' has the necessary elements */ if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err; if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err; if (generator <= 1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); goto err; } if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1,24)) goto err; if (!BN_set_word(t2,11)) goto err; g=2; } #if 0 /* does not work for safe primes */ else if (generator == DH_GENERATOR_3) { if (!BN_set_word(t1,12)) goto err; if (!BN_set_word(t2,5)) goto err; g=3; } #endif else if (generator == DH_GENERATOR_5) { if (!BN_set_word(t1,10)) goto err; if (!BN_set_word(t2,3)) goto err; /* BN_set_word(t3,7); just have to miss * out on these ones :-( */ g=5; } else { /* in the general case, don't worry if 'generator' is a * generator or not: since we are using safe primes, * it will generate either an order-q or an order-2q group, * which both is OK */ if (!BN_set_word(t1,2)) goto err; if (!BN_set_word(t2,1)) goto err; g=generator; } if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; if (!BN_set_word(ret->g,g)) goto err; ok=1; err: if (ok == -1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
BigNumber::BigNumber(uint32 val) : _bn(BN_new()) { BN_set_word(_bn, val); }
void printnumber(FILE *f, const struct number *b, u_int base) { struct number *int_part, *fract_part; int digits; char buf[11]; size_t sz; int i; struct stack stack; char *p; charcount = 0; lastchar = -1; if (BN_is_zero(b->number)) putcharwrap(f, '0'); int_part = new_number(); fract_part = new_number(); fract_part->scale = b->scale; if (base <= 16) digits = 1; else { digits = snprintf(buf, sizeof(buf), "%u", base-1); } split_number(b, int_part->number, fract_part->number); i = 0; stack_init(&stack); while (!BN_is_zero(int_part->number)) { BN_ULONG rem = BN_div_word(int_part->number, base); stack_pushstring(&stack, get_digit(rem, digits, base)); i++; } sz = i; if (BN_cmp(b->number, &zero) < 0) putcharwrap(f, '-'); for (i = 0; i < sz; i++) { p = stack_popstring(&stack); if (base > 16) putcharwrap(f, ' '); printwrap(f, p); free(p); } stack_clear(&stack); if (b->scale > 0) { struct number *num_base; BIGNUM mult, stop; putcharwrap(f, '.'); num_base = new_number(); BN_set_word(num_base->number, base); BN_init(&mult); BN_one(&mult); BN_init(&stop); BN_one(&stop); scale_number(&stop, b->scale); i = 0; while (BN_cmp(&mult, &stop) < 0) { u_long rem; if (i && base > 16) putcharwrap(f, ' '); i = 1; bmul_number(fract_part, fract_part, num_base); split_number(fract_part, int_part->number, NULL); rem = BN_get_word(int_part->number); p = get_digit(rem, digits, base); int_part->scale = 0; normalize(int_part, fract_part->scale); BN_sub(fract_part->number, fract_part->number, int_part->number); printwrap(f, p); free(p); BN_mul_word(&mult, base); } free_number(num_base); BN_free(&mult); BN_free(&stop); } flushwrap(f); free_number(int_part); free_number(fract_part); }
int DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes) { BIGNUM *bn = NULL, *sum = NULL; int ret = 0; *codes = 0; /** * Checks that the function performs are: * - pub_key is not negative */ if (BN_is_negative(pub_key)) goto out; /** * - pub_key > 1 and pub_key < p - 1, * to avoid small subgroups attack. */ bn = BN_new(); if (bn == NULL) goto out; if (!BN_set_word(bn, 1)) goto out; if (BN_cmp(bn, pub_key) >= 0) *codes |= DH_CHECK_PUBKEY_TOO_SMALL; sum = BN_new(); if (sum == NULL) goto out; BN_uadd(sum, pub_key, bn); if (BN_cmp(sum, dh->p) >= 0) *codes |= DH_CHECK_PUBKEY_TOO_LARGE; /** * - if g == 2, pub_key have more then one bit set, * if bits set is 1, log_2(pub_key) is trival */ if (!BN_set_word(bn, 2)) goto out; if (BN_cmp(bn, dh->g) == 0) { unsigned i, n = BN_num_bits(pub_key); unsigned bits = 0; for (i = 0; i <= n; i++) if (BN_is_bit_set(pub_key, i)) bits++; if (bits < 2) { *codes |= DH_CHECK_PUBKEY_TOO_SMALL; goto out; } } ret = 1; out: if (bn) BN_free(bn); if (sum) BN_free(sum); return ret; }
/* ------------------------------------------------------------------ */ char *eg_encode (char *s, int length, char *public_key) { // we use NULL-with-random padding. this allows to pass // NULL-terminated strings without any additional processing. // if you want to exchange binary data, define your own padding in // your application or pass the data length somehow BIGNUM message, gamma, delta, k, temp; BIGNUM *p=NULL, *g=NULL, *key=NULL; int i, nl, nc, no, pc, rc1, rc2, rc3, index; unsigned char *buf = NULL; BN_CTX *ctx = NULL; char *p1, *p2, *p3, *output; // setup key (p, g, key) p1 = strdup (public_key); p2 = strchr (p1, ':'); if (p2 == NULL) {free (p1); return NULL;} *p2 = '\0'; p3 = strchr (p1, ','); if (p3 == NULL) { index = atoi (p1); if (index > sizeof(precomp)/sizeof(precomp[0])-1) return NULL; p = NULL; rc1 = BN_hex2bn (&p, precomp[index].prime); if (rc1 == 0) return NULL; g = BN_new (); if (g == NULL) return NULL; BN_set_word (g, precomp[index].generator); } else { rc1 = BN_hex2bn (&p, p1); rc2 = BN_hex2bn (&g, p3+1); if (rc1 == 0 || rc2 == 0) return NULL; } rc3 = BN_hex2bn (&key, p2+1); free (p1); if (rc3 == 0) return NULL; // initialize temp variables BN_init (&message); BN_init (&gamma); BN_init (&delta); BN_init (&k); BN_init (&temp); ctx = BN_CTX_new (); if (ctx == NULL) return NULL; // number of bytes in p. this is the amount of bytes // we can convert in one gulp nl = BN_num_bytes (p); buf = malloc (nl); if (buf == NULL) return NULL; // compute the 'nc', the number of cycles (gulps) nc = length/nl; if (length % nl) nc++; // preallocate output buffer: nl*2 -- bin->hex conversion, // nl*2*2 + 1 -- each gulp consists of two bignums and comma // between them, nl*2*2+1+1 -- spaces between gulps in the output no = nc * (nl*2*2+1+1) + 1; output = malloc (no); if (output == NULL) return NULL; output[0] = '\0'; // cycle by pieces of input, each piece is 'nl' bytes long // (except the last one) for (i=0; i<nc; i++) { // compute piece length pc = (i == nc-1) ? length % nl : nl; memcpy (buf, s+i*nl, pc); // do NULL+random padding if necessary if (pc != nl) { buf[pc] = '\0'; if (nl-pc-1 > 0) rand_bytes (buf+pc+1, nl-pc-1); } // convert to bignum BN_bin2bn (buf, nl, &message); // ElGamal: get random k, gamma = g^k mod p, delta = message * key^k mod p BN_rand (&k, BN_num_bits (p)-1, 0, 0); BN_mod_exp (&gamma, g, &k, p, ctx); BN_mod_exp (&temp, key, &k, p, ctx); BN_mod_mul (&delta, &temp, &message, p, ctx); // convert into hex p1 = BN_bn2hex (&gamma); p2 = BN_bn2hex (&delta); // copy result to output buffer and add delimiting space // fairly ineffective at the moment strcat (output, p1); strcat (output, ","); strcat (output, p2); if (i != nc-1) strcat (output, " "); free (p1); free (p2); } BN_CTX_free (ctx); BN_clear_free (p); BN_clear_free (g); BN_clear_free (key); memset (buf, 0, nl); free(buf); return output; }
int main(int argc, char* argv[]){ // Local Variable definitions int i, j, k; size_t ret; int rsa_byte_size = RSA_KEY_SIZE/8; // buffer used to seed the PRNG unsigned char seed[rsa_byte_size]; //unsigned char *keybuff; unsigned char *priv; unsigned char *pub; unsigned char *mod; size_t keybuff_len=0; // File pointers FILE *urand; FILE *pubkeyfile; FILE *privkeyfile; // RSA Struct used to store Priv/Pub key vals RSA *key = RSA_new(); // Set the exponent size, e, to be used by RSA. BIGNUM *e = BN_new(); // Open the public keyfile pubkeyfile = fopen("./publickey.txt","w+"); if(pubkeyfile == NULL){ fprintf(stderr, "ERROR: Unable to open publickey.txt for writing!\n"); exit(-1); } // Open the private keyfile privkeyfile = fopen("./secretkey.txt","w+"); if(privkeyfile == NULL){ fprintf(stderr, "ERROR: Unable to open privatekey.txt for writing!\n"); exit(-1); } // Open dev rand to seed our random data. urand = fopen("/dev/urandom","r"); if(urand == NULL){ fprintf(stderr, "ERROR: Unable to open /dev/urandom for reading!\n"); exit(-1); } // Read the rand data from /dev/urandom ret = fread(&seed, sizeof(char), RSA_KEY_SIZE/8, urand); if(ret < RSA_KEY_SIZE/8){ fprintf(stderr, "ERROR: Unable to obtain random seed from /dev/urandom!\n"); exit(-1); } // Seed the PRNG RAND_seed(&seed, RSA_KEY_SIZE/8); // Setup our BIGNUM, this acts as the exponent e and will be stored with the pub/priv keys struct // read the BN_rand description to see why the last two args are 1. //ret = BN_generate_prime_ex(e, RSA_KEY_SIZE, 1, NULL, NULL, NULL); ret = BN_set_word(e, 0x10001); // 65537 if(!ret){ fprintf(stderr, "ERROR: There was a problem generating the mod 'e'\n"); exit(-1); } // NOTE: As per the OpenSSL docs, RSA_generate_key(...) is deprecated. // int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); // Generate the RSA keys ret = RSA_generate_key_ex(key, RSA_KEY_SIZE, e, NULL); /* Currently, the OpenSSL doc does not detail the return value of RSA_generate_key_ex :-( */ if(!ret){ fprintf(stderr, "ERROR: There was a problem generating RSA key!\n"); exit(-1); } /* printf("DBG: Public Key - "); char * n_val = BN_bn2hex(key->n); for(i = 0; i < 256; i++){ printf("%c", n_val[i]); } printf("\n"); */ if(!PEM_write_RSAPublicKey(pubkeyfile, key)){ fprintf(stderr, "ERROR: There was a problem writing the Public RSA key!\n"); exit(-1); } if(!PEM_write_RSAPrivateKey(privkeyfile, key, NULL, NULL, 0, NULL, NULL)){ fprintf(stderr, "ERROR: There was a problem writing the Private RSA key!\n"); exit(-1); } /* // Write the public and private key values out to disk respectively //i = BN_num_bytes(key->e); //j = BN_num_bits(key->e); //keybuff = BN_bn2hex(key->e); priv = BN_bn2hex(key->d); pub = BN_bn2hex(key->e); mod = BN_bn2hex(key->n); // Write out the public modulus, n j = BN_num_bytes(key->e); for(i = 0; i < j; i++){ fprintf(pubkeyfile, "%c", mod[i]); fprintf(privkeyfile, "%c", mod[i]); } fprintf(pubkeyfile,"\n"); fprintf(privkeyfile,"\n"); // Write out the public key j = BN_num_bytes(key->e); for(i = 0; i < j; i++){ fprintf(pubkeyfile, "%c", pub[i]); } // Write out the private key j = BN_num_bytes(key->d); for(i = 0; i < j; i++){ fprintf(privkeyfile, "%c", priv[i]); } */ //printf("DBG: Number of bytes in e - %d\n", i); //DBG: Number of bytes in e - 256 //printf("DBG: Number of bits in e - %d\n", j); //DBG: Number of bits in e - 2048 /* printf("DBG: Print e:\n"); for(k = 0; k < i; k++){ printf("%c",keybuff[k]); } printf("\nDone.\n"); // Note, the below is 256 characters, or 2048 bits worth of data. DBG: Print e: DF61CD9DCFF8B60F8302098EEA099F1B9ECED5C5AD3C98E129D380121A765BE089D6FAFEBACF272B5A87FC98995 A259D6F9D069805436F0B93AFBB02ABAD2C19DD767F25DC25226DA99B24C92727A0F583FE8CAD4C60702A1F4EDB 7F8E3A872519A8515DCBB963E676939FDCC2DFFD40C970137952FADB5048F7DAB4632646C8 Done. */ // Free allocated memory fclose(urand); fclose(pubkeyfile); fclose(privkeyfile); // Free the allocated RSA structures. RSA_free(key); BN_free(e); return 1; }
/* ------------------------------------------------------------------ */ int eg_decode (char *s, char *private_key, char **result) { // there is no any padding processing in the decoding routine // (see comment in rsa_encode) BIGNUM message, *gamma, *delta, k, temp1, temp2, one; BIGNUM *p=NULL, *g=NULL, *key=NULL; int i, nl, nc, rc1, rc2, rc3, length, index; unsigned char *buf = NULL; BN_CTX *ctx = NULL; char *p1, *p2, *p3; // setup key (p, g, key) p1 = strdup (private_key); p2 = strchr (p1, ':'); if (p2 == NULL) {free (p1); return -1;} *p2 = '\0'; p3 = strchr (p1, ','); if (p3 == NULL) { index = atoi (p1); if (index > sizeof(precomp)/sizeof(precomp[0])-1) return -1; p = NULL; rc1 = BN_hex2bn (&p, precomp[index].prime); if (rc1 == 0) return -1; g = BN_new (); if (g == NULL) return -1; BN_set_word (g, precomp[index].generator); } else { rc1 = BN_hex2bn (&p, p1); rc2 = BN_hex2bn (&g, p3+1); if (rc1 == 0 || rc2 == 0) return -1; } rc3 = BN_hex2bn (&key, p2+1); free (p1); if (rc3 == 0) return -1; // initialize temp variables BN_init (&message); BN_init (&k); BN_init (&temp1); BN_init (&temp2); BN_init (&one); BN_one (&one); gamma = BN_new (); if (gamma == NULL) return -1; delta = BN_new (); if (delta == NULL) return -1; ctx = BN_CTX_new (); if (ctx == NULL) return -1; // number of bytes in the modulus. this is the amount of bytes // we can convert in one gulp and should expect to be in one // group nl = BN_num_bytes (p); buf = malloc (nl); if (buf == NULL) return -1; // find the number of pieces in the encrypted message (the last // piece is not terminated with space) nc = str_numchars (s, ' ') + 1; // preallocate output buffer length = nc * nl; *result = malloc (length); if (*result == NULL) return -1; // cycle by pieces of input, each piece is 'nl' bytes long // (except the last one) p1 = s; for (i=0; i<nc; i++) { // extract next piece p2 = strchr (p1, ' '); if (p2 == NULL) { if (i != nc-1) return -1; } else { *p2 = '\0'; } p3 = strchr (p1, ','); if (p3 == NULL) return -1; *p3++ = '\0'; // convert to bignum rc1 = BN_hex2bn (&gamma, p1); if (rc1 == 0) return -1; rc1 = BN_hex2bn (&delta, p3); if (rc1 == 0) return -1; // ElGamal BN_sub (&temp1, p, &one); BN_sub (&temp2, &temp1, key); BN_mod_exp (&temp1, gamma, &temp2, p, ctx); BN_mod_mul (&message, &temp1, delta, p, ctx); // convert into binary output BN_bn2bin (&message, (unsigned char *)(*result+i*nl)); // advance pointer to prepare search for next piece p1 = p2 + 1; } BN_CTX_free (ctx); memset (buf, 0, nl); free(buf); return length; }
static int cert_init() { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; BIGNUM *exponent = NULL, *serial_number = NULL; RSA *rsa = NULL; ASN1_INTEGER *asn1_serial_number; X509_NAME *name; struct dtls_cert *new_cert; ilog(LOG_INFO, "Generating new DTLS certificate"); /* objects */ pkey = EVP_PKEY_new(); exponent = BN_new(); rsa = RSA_new(); serial_number = BN_new(); name = X509_NAME_new(); x509 = X509_new(); if (!exponent || !pkey || !rsa || !serial_number || !name || !x509) goto err; /* key */ if (!BN_set_word(exponent, 0x10001)) goto err; if (!RSA_generate_key_ex(rsa, 1024, exponent, NULL)) goto err; if (!EVP_PKEY_assign_RSA(pkey, rsa)) goto err; /* x509 cert */ if (!X509_set_pubkey(x509, pkey)) goto err; /* serial */ if (!BN_pseudo_rand(serial_number, 64, 0, 0)) goto err; asn1_serial_number = X509_get_serialNumber(x509); if (!asn1_serial_number) goto err; if (!BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) goto err; /* version 1 */ if (!X509_set_version(x509, 0L)) goto err; /* common name */ if (!X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8, (unsigned char *) "rtpengine", -1, -1, 0)) goto err; if (!X509_set_subject_name(x509, name)) goto err; if (!X509_set_issuer_name(x509, name)) goto err; /* cert lifetime */ if (!X509_gmtime_adj(X509_get_notBefore(x509), -60*60*24)) goto err; if (!X509_gmtime_adj(X509_get_notAfter(x509), CERT_EXPIRY_TIME)) goto err; /* sign it */ if (!X509_sign(x509, pkey, EVP_sha1())) goto err; /* digest */ new_cert = obj_alloc0("dtls_cert", sizeof(*new_cert), cert_free); new_cert->fingerprint.hash_func = &hash_funcs[0]; dtls_fingerprint_hash(&new_cert->fingerprint, x509); new_cert->x509 = x509; new_cert->pkey = pkey; new_cert->expires = time(NULL) + CERT_EXPIRY_TIME; dump_cert(new_cert); /* swap out certs */ rwlock_lock_w(&__dtls_cert_lock); if (__dtls_cert) obj_put(__dtls_cert); __dtls_cert = new_cert; rwlock_unlock_w(&__dtls_cert_lock); /* cleanup */ BN_free(exponent); BN_free(serial_number); X509_NAME_free(name); return 0; err: ilog(LOG_ERROR, "Failed to generate DTLS certificate"); if (pkey) EVP_PKEY_free(pkey); if (exponent) BN_free(exponent); if (rsa) RSA_free(rsa); if (x509) X509_free(x509); if (serial_number) BN_free(serial_number); return -1; }
static int test_BN_uadd(void) { BIGNUM *a, *b, *c; char *p; a = BN_new(); b = BN_new(); c = BN_new(); BN_set_word(a, 1); BN_set_word(b, 2); BN_uadd(c, a, b); if (BN_get_word(c) != 3) return 1; BN_uadd(c, b, a); if (BN_get_word(c) != 3) return 1; BN_set_word(b, 0xff); BN_uadd(c, a, b); if (BN_get_word(c) != 0x100) return 1; BN_uadd(c, b, a); if (BN_get_word(c) != 0x100) return 1; BN_set_word(a, 0xff); BN_uadd(c, a, b); if (BN_get_word(c) != 0x1fe) return 1; BN_uadd(c, b, a); if (BN_get_word(c) != 0x1fe) return 1; BN_free(a); BN_free(b); BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2"); BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA"); BN_uadd(c, b, a); p = BN_bn2hex(c); if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) { free(p); return 1; } free(p); BN_uadd(c, a, b); p = BN_bn2hex(c); if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) { free(p); return 1; } free(p); BN_free(a); BN_free(b); BN_free(c); return 0; }
BigNumber::BigNumber(uint32 val) { _bn = BN_new(); BN_set_word(_bn, val); _array = NULL; }
static int test_BN_bit(void) { BIGNUM *bn; int ret = 0; bn = BN_new(); /* test setting and getting of "word" */ if (!BN_set_word(bn, 1)) return 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_set_word(bn, 2)) return 1; if (!BN_is_bit_set(bn, 1)) ret += 1; if (!BN_set_word(bn, 3)) return 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_is_bit_set(bn, 1)) ret += 1; if (!BN_set_word(bn, 0x100)) return 1; if (!BN_is_bit_set(bn, 8)) ret += 1; if (!BN_set_word(bn, 0x1000)) return 1; if (!BN_is_bit_set(bn, 12)) ret += 1; /* test bitsetting */ if (!BN_set_word(bn, 1)) return 1; if (!BN_set_bit(bn, 1)) return 1; if (BN_get_word(bn) != 3) return 1; if (!BN_clear_bit(bn, 0)) return 1; if (BN_get_word(bn) != 2) return 1; /* test bitsetting past end of current end */ BN_clear(bn); if (!BN_set_bit(bn, 12)) return 1; if (BN_get_word(bn) != 0x1000) return 1; /* test bit and byte counting functions */ if (BN_num_bits(bn) != 13) return 1; if (BN_num_bytes(bn) != 2) return 1; BN_free(bn); return ret; }
static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key) { unsigned char *pubkey = NULL; DWORD len; BLOBHEADER *bh; RSA *rkey = NULL; DSA *dkey = NULL; EVP_PKEY *ret = NULL; if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); capi_addlasterror(); return NULL; } pubkey = OPENSSL_malloc(len); if (!pubkey) goto memerr; if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); capi_addlasterror(); goto err; } bh = (BLOBHEADER *)pubkey; if (bh->bType != PUBLICKEYBLOB) { CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); goto err; } if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) { RSAPUBKEY *rp; DWORD rsa_modlen; unsigned char *rsa_modulus; rp = (RSAPUBKEY *)(bh + 1); if (rp->magic != 0x31415352) { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", rp->magic); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } rsa_modulus = (unsigned char *)(rp + 1); rkey = RSA_new_method(eng); if (!rkey) goto memerr; rkey->e = BN_new(); rkey->n = BN_new(); if (!rkey->e || !rkey->n) goto memerr; if (!BN_set_word(rkey->e, rp->pubexp)) goto memerr; rsa_modlen = rp->bitlen / 8; if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen)) goto memerr; RSA_set_ex_data(rkey, rsa_capi_idx, key); if (!(ret = EVP_PKEY_new())) goto memerr; EVP_PKEY_assign_RSA(ret, rkey); rkey = NULL; } else if (bh->aiKeyAlg == CALG_DSS_SIGN) { DSSPUBKEY *dp; DWORD dsa_plen; unsigned char *btmp; dp = (DSSPUBKEY *)(bh + 1); if (dp->magic != 0x31535344) { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", dp->magic); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } dsa_plen = dp->bitlen / 8; btmp = (unsigned char *)(dp + 1); dkey = DSA_new_method(eng); if (!dkey) goto memerr; dkey->p = BN_new(); dkey->q = BN_new(); dkey->g = BN_new(); dkey->pub_key = BN_new(); if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key) goto memerr; if (!lend_tobn(dkey->p, btmp, dsa_plen)) goto memerr; btmp += dsa_plen; if (!lend_tobn(dkey->q, btmp, 20)) goto memerr; btmp += 20; if (!lend_tobn(dkey->g, btmp, dsa_plen)) goto memerr; btmp += dsa_plen; if (!lend_tobn(dkey->pub_key, btmp, dsa_plen)) goto memerr; btmp += dsa_plen; DSA_set_ex_data(dkey, dsa_capi_idx, key); if (!(ret = EVP_PKEY_new())) goto memerr; EVP_PKEY_assign_DSA(ret, dkey); dkey = NULL; } else { char algstr[10]; BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); ERR_add_error_data(2, "aiKeyAlg=0x", algstr); goto err; } err: if (pubkey) OPENSSL_free(pubkey); if (!ret) { if (rkey) RSA_free(rkey); if (dkey) DSA_free(dkey); } return ret; memerr: CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE); goto err; }
static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { EC_GROUP *group = NULL; EC_POINT *P = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL; int ok = 0; unsigned param_len; const EC_METHOD *meth; const struct curve_data *data; const uint8_t *params; if ((ctx = BN_CTX_new()) == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } data = curve->data; param_len = data->param_len; params = data->data; if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } if (curve->method != 0) { meth = curve->method(); if (((group = ec_group_new(meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); goto err; } } else { if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); goto err; } } if ((P = EC_POINT_new(group)) == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); goto err; } if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); goto err; } if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) || !BN_set_word(x, (BN_ULONG)data->cofactor)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } group->generator = P; P = NULL; if (!BN_copy(&group->order, order) || !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } ok = 1; err: if (!ok) { EC_GROUP_free(group); group = NULL; } EC_POINT_free(P); BN_CTX_free(ctx); BN_free(p); BN_free(a); BN_free(b); BN_free(order); BN_free(x); BN_free(y); return group; }
int MAIN(int argc, char **argv) { BN_GENCB cb; #ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; #endif int ret=1; int i,num=DEFBITS; long l; const EVP_CIPHER *enc=NULL; unsigned long f4=RSA_F4; char *outfile=NULL; char *passargout = NULL, *passout = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif char *inrand=NULL; BIO *out=NULL; BIGNUM *bn = BN_new(); RSA *rsa = NULL; if(!bn) goto err; apps_startup(); BN_GENCB_set(&cb, genrsa_cb, bio_err); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,OPENSSL_TYPE__FILE_STDERR,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto err; if ((out=BIO_new(BIO_s_file())) == NULL) { BIO_printf(bio_err,"unable to create BIO for output\n"); goto err; } argv++; argc--; for (;;) { if (argc <= 0) break; if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-3") == 0) f4=3; else if (TINYCLR_SSL_STRCMP(*argv,"-F4") == 0 || TINYCLR_SSL_STRCMP(*argv,"-f4") == 0) f4=RSA_F4; #ifndef OPENSSL_NO_ENGINE else if (TINYCLR_SSL_STRCMP(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (TINYCLR_SSL_STRCMP(*argv,"-rand") == 0) { if (--argc < 1) goto bad; inrand= *(++argv); } #ifndef OPENSSL_NO_DES else if (TINYCLR_SSL_STRCMP(*argv,"-des") == 0) enc=EVP_des_cbc(); else if (TINYCLR_SSL_STRCMP(*argv,"-des3") == 0) enc=EVP_des_ede3_cbc(); #endif #ifndef OPENSSL_NO_IDEA else if (TINYCLR_SSL_STRCMP(*argv,"-idea") == 0) enc=EVP_idea_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (TINYCLR_SSL_STRCMP(*argv,"-seed") == 0) enc=EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_AES else if (TINYCLR_SSL_STRCMP(*argv,"-aes128") == 0) enc=EVP_aes_128_cbc(); else if (TINYCLR_SSL_STRCMP(*argv,"-aes192") == 0) enc=EVP_aes_192_cbc(); else if (TINYCLR_SSL_STRCMP(*argv,"-aes256") == 0) enc=EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (TINYCLR_SSL_STRCMP(*argv,"-camellia128") == 0) enc=EVP_camellia_128_cbc(); else if (TINYCLR_SSL_STRCMP(*argv,"-camellia192") == 0) enc=EVP_camellia_192_cbc(); else if (TINYCLR_SSL_STRCMP(*argv,"-camellia256") == 0) enc=EVP_camellia_256_cbc(); #endif else if (TINYCLR_SSL_STRCMP(*argv,"-passout") == 0) { if (--argc < 1) goto bad; passargout= *(++argv); } else break; argv++; argc--; } if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0))) { bad: BIO_printf(bio_err,"usage: genrsa [args] [numbits]\n"); BIO_printf(bio_err," -des encrypt the generated key with DES in cbc mode\n"); BIO_printf(bio_err," -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err," -idea encrypt the generated key with IDEA in cbc mode\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf(bio_err," -seed\n"); BIO_printf(bio_err," encrypt PEM output with cbc seed\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err," -aes128, -aes192, -aes256\n"); BIO_printf(bio_err," encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err," encrypt PEM output with cbc camellia\n"); #endif BIO_printf(bio_err," -out file output the key to 'file\n"); BIO_printf(bio_err," -passout arg output file pass phrase source\n"); BIO_printf(bio_err," -f4 use F4 (0x10001) for the E value\n"); BIO_printf(bio_err," -3 use 3 for the E value\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err," load the file (or the files in the directory) into\n"); BIO_printf(bio_err," the random number generator\n"); goto err; } ERR_load_crypto_strings(); if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto err; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (outfile == NULL) { BIO_set_fp(out,OPENSSL_TYPE__FILE_STDOUT,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { TINYCLR_SSL_PERROR(outfile); goto err; } } if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n", num); #ifdef OPENSSL_NO_ENGINE rsa = RSA_new(); #else rsa = RSA_new_method(e); #endif if (!rsa) goto err; if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) goto err; app_RAND_write_file(NULL, bio_err); /* We need to do the following for when the base number size is < * long, esp windows 3.1 :-(. */ l=0L; for (i=0; i<rsa->e->top; i++) { #ifndef SIXTY_FOUR_BIT l<<=BN_BITS4; l<<=BN_BITS4; #endif l+=rsa->e->d[i]; } BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l); { PW_CB_DATA cb_data; cb_data.password = passout; cb_data.prompt_info = outfile; if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0, (pem_password_cb *)password_callback,&cb_data)) goto err; } ret=0; err: if (bn) BN_free(bn); if (rsa) RSA_free(rsa); if (out) BIO_free_all(out); if(passout) OPENSSL_free(passout); if (ret != 0) ERR_print_errors(bio_err); apps_shutdown(); OPENSSL_EXIT(ret); }
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 dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok = 0; unsigned char seed[SHA256_DIGEST_LENGTH]; unsigned char md[SHA256_DIGEST_LENGTH]; unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; BIGNUM *r0, *W, *X, *c, *test; BIGNUM *g = NULL, *q = NULL, *p = NULL; BN_MONT_CTX *mont = NULL; int i, k, n = 0, m = 0, qsize = qbits >> 3; int counter = 0; int r = 0; BN_CTX *ctx = NULL; unsigned int h = 2; if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) /* invalid q size */ return 0; if (evpmd == NULL) /* use SHA1 as default */ evpmd = EVP_sha1(); if (bits < 512) bits = 512; bits = (bits + 63) / 64 * 64; /* * NB: seed_len == 0 is special case: copy generated seed to * seed_in if it is not NULL. */ if (seed_len && seed_len < (size_t)qsize) seed_in = NULL; /* seed buffer too small -- ignore */ /* * App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits */ if (seed_len > (size_t)qsize) seed_len = qsize; if (seed_in != NULL) memcpy(seed, seed_in, seed_len); if ((ctx=BN_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test, BN_value_one(), bits - 1)) goto err; for (;;) { for (;;) { /* find q */ int seed_is_random; /* step 1 */ if (!BN_GENCB_call(cb, 0, m++)) goto err; if (!seed_len) { RAND_pseudo_bytes(seed, qsize); seed_is_random = 1; } else { seed_is_random = 0; /* use random seed if 'seed_in' turns out to be bad */ seed_len = 0; } memcpy(buf, seed, qsize); memcpy(buf2, seed, qsize); /* precompute "SEED + 1" for step 7: */ for (i = qsize - 1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } /* step 2 */ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) goto err; if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) goto err; for (i = 0; i < qsize; i++) md[i] ^= buf2[i]; /* step 3 */ md[0] |= 0x80; md[qsize - 1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) goto err; /* step 4 */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) break; if (r != 0) goto err; /* do a callback call */ /* step 5 */ } if (!BN_GENCB_call(cb, 2, 0)) goto err; if (!BN_GENCB_call(cb, 3, 0)) goto err; /* step 6 */ counter = 0; /* "offset = 2" */ n = (bits - 1) / 160; for (;;) { if (counter != 0 && !BN_GENCB_call(cb, 0, counter)) goto err; /* step 7 */ BN_zero(W); /* now 'buf' contains "SEED + offset - 1" */ for (k = 0; k <= n; k++) { /* obtain "SEED + offset + k" by incrementing: */ for (i = qsize - 1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL)) goto err; /* step 8 */ if (!BN_bin2bn(md, qsize, r0)) goto err; if (!BN_lshift(r0, r0, (qsize << 3) * k)) goto err; if (!BN_add(W, W, r0)) goto err; } /* more of step 8 */ if (!BN_mask_bits(W, bits - 1)) goto err; if (!BN_copy(X, W)) goto err; if (!BN_add(X, X, test)) goto err; /* step 9 */ if (!BN_lshift1(r0, q)) goto err; if (!BN_mod(c, X, r0, ctx)) goto err; if (!BN_sub(r0, c, BN_value_one())) goto err; if (!BN_sub(p, X, r0)) goto err; /* step 10 */ if (BN_cmp(p, test) >= 0) { /* step 11 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ if (r != 0) goto err; } /* step 13 */ counter++; /* "offset = offset + n + 1" */ /* step 14 */ if (counter >= 4096) break; } } end: if (!BN_GENCB_call(cb, 2, 1)) goto err; /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test, p, BN_value_one())) goto err; if (!BN_div(r0, NULL, test, q, ctx)) goto err; if (!BN_set_word(test, h)) goto err; if (!BN_MONT_CTX_set(mont, p, ctx)) goto err; for (;;) { /* g=test^r0%p */ if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test, test, BN_value_one())) goto err; h++; } if (!BN_GENCB_call(cb, 3, 1)) goto err; ok = 1; err: if (ok) { if (ret->p) BN_free(ret->p); if (ret->q) BN_free(ret->q); if (ret->g) BN_free(ret->g); ret->p = BN_dup(p); ret->q = BN_dup(q); ret->g = BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok = 0; goto err; } if (counter_ret != NULL) *counter_ret = counter; if (h_ret != NULL) *h_ret = h; if (seed_out) memcpy(seed_out, seed, qsize); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
/* * Generate key */ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { #ifndef ENABLE_OPENSSL return SC_ERROR_NOT_SUPPORTED; #else int r = SC_ERROR_UNKNOWN; long lg; u8 *p; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; RSA *rsa = NULL; BIGNUM *bn = NULL; BIO *mem = NULL; sc_file_t *prkf = NULL; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { return SC_ERROR_NOT_SUPPORTED; } #if OPENSSL_VERSION_NUMBER>=0x00908000L rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); if(rsa == NULL || bn == NULL || mem == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL)) #else mem = BIO_new(BIO_s_mem()); if(mem == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL); if (!rsa) #endif { r = SC_ERROR_UNKNOWN; goto out; } rsa->meth = RSA_PKCS1_SSLeay(); if(pubkey != NULL) { if(!i2d_RSAPublicKey_bio(mem, rsa)) { r = SC_ERROR_UNKNOWN; goto out; } lg = BIO_get_mem_data(mem, &p); pubkey->algorithm = SC_ALGORITHM_RSA; r = sc_pkcs15_decode_pubkey(p15card->card->ctx, pubkey, p, lg); } (void) BIO_reset(mem); if(!i2d_RSAPrivateKey_bio(mem, rsa)) { r = SC_ERROR_UNKNOWN; goto out; } lg = BIO_get_mem_data(mem, &p); /* Get the private key file */ r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf); if (r < 0) { char pbuf[SC_MAX_PATH_STRING_SIZE]; r = sc_path_print(pbuf, sizeof(pbuf), &key_info->path); if (r != SC_SUCCESS) pbuf[0] = '\0'; goto out; } prkf->size = lg; r = sc_pkcs15init_create_file(profile, p15card, prkf); if(r) goto out; r = sc_pkcs15init_update_file(profile, p15card, prkf, p, lg); if(r) goto out; out: if(mem) BIO_free(mem); if(bn) BN_free(bn); if(rsa) RSA_free(rsa); if(prkf) sc_file_free(prkf); return r; #endif }