static void ZHJPAKE_Message_release(ZHJPAKE_Message *message) { BN_free(message->y); }
static void YAK_ZKP_release(YAK_ZKP *zkp) { BN_free(zkp->b); BN_free(zkp->gr); }
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); }
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx) { int retry_counter = 32; BN_BLINDING *ret = NULL; if (b == NULL) ret = BN_BLINDING_new(NULL, NULL, m); else ret = b; if (ret == NULL) goto err; if (ret->A == NULL && (ret->A = BN_new()) == NULL) goto err; if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) goto err; if (e != NULL) { if (ret->e != NULL) BN_free(ret->e); ret->e = BN_dup(e); } if (ret->e == NULL) goto err; if (bn_mod_exp != NULL) ret->bn_mod_exp = bn_mod_exp; if (m_ctx != NULL) ret->m_ctx = m_ctx; do { if (!BN_rand_range(ret->A, ret->mod)) goto err; if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) { /* this should almost never happen for good RSA keys */ unsigned long error = ERR_peek_last_error(); if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) { if (retry_counter-- == 0) { BNerr(BN_F_BN_BLINDING_CREATE_PARAM, BN_R_TOO_MANY_ITERATIONS); goto err; } ERR_clear_error(); } else goto err; } else break; } while (1); if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) goto err; } else { if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) goto err; } return ret; err: if (b == NULL && ret != NULL) { BN_BLINDING_free(ret); ret = NULL; } return ret; }
int main() { BIGNUM *x, *y, *exp, *m, *order, *cof; BIGNUM t, store[30]; COMPLEX *a, *b, *r; EC_POINT *point, *Q; int i; x = BN_new(); y = BN_new(); order = BN_new(); exp = BN_new(); m = BN_new(); a = COMP_new(); b = COMP_new(); r = COMP_new(); for( i = 0; i < 30; i++ ) BN_init( &(store[i]) ); if ( Context == NULL ) Context = BN_CTX_new(); bi_init( &malloc ); group = EC_GROUP_new( EC_GFp_simple_method() ); if ( group == NULL ) goto err; if(!BN_set_word(m, 43l)) goto err; BN_set_word(x, 1l); BN_set_word(y, 0l); if ( !EC_GROUP_set_curve_GFp( group, m, x, y, Context) ) goto err; BN_set_word(x, 23l); BN_set_word(y, 8l); BN_set_word(order, 11l); point = EC_POINT_new( group ); EC_POINT_set_affine_coordinates_GFp( group, point, x, y, Context ); cof = BN_new(); BN_set_word( cof, 4 ); EC_GROUP_set_generator( group, point, order, cof ); if ( EC_GROUP_check( group, Context ) ) printf(" group set is ok \n"); TSS_DAA_ISSUER_KEY issuer_key; TSS_DAA_ISSUER_PROOF issuer_proof; TSS_DAA_JOIN_issuer_setup(&issuer_key, &issuer_proof); // printf("\n"); // BN_set_word(x, 41l); // BN_mod_inverse(x, x, m, Context); // BN_print_fp(stdout, x); // // printf("\n"); // BN_set_word(x, 11l); // BN_mod_inverse(x, x, m, Context); // BN_print_fp(stdout, x); char *str = "abcdefghijklmnop"; Q = map_to_point( str ); BN_set_word(x, 23l); BN_set_word(y, 8l); BN_set_word(order, 11l); Q = EC_POINT_new( group ); EC_POINT_set_affine_coordinates_GFp( group, Q, x, y, Context ); Tate( point, Q, order, 0, store, a ); printf("tate pair t(p, Q) =:\n a.x: "); BN_print_fp(stdout, &a->x); printf("\na.y: "); BN_print_fp(stdout, &a->y); EC_POINT_dbl( group, point, point, Context); EC_POINT_get_affine_coordinates_GFp( group, point, x, y, Context); printf("2A.x =:\n"); BN_print_fp(stdout, x); printf("2P.y= :\n"); BN_print_fp(stdout, y); Tate( point, Q, order, 0, store, a ); printf("tate pair t(2p, Q) =:\n a.x: "); BN_print_fp(stdout, &a->x); printf("\na.y: "); BN_print_fp(stdout, &a->y); BN_free( x ); BN_free( y ); BN_free( exp ); BN_free( m ); BN_free( order ); BN_free( cof ); COMP_free( a ); COMP_free( b ); COMP_free( r ); return 0; err: BN_free( &t ); BN_free( x ); BN_free( y ); BN_free( exp ); BN_free( m ); BN_free( order ); BN_free( cof ); COMP_free( a ); COMP_free( b ); COMP_free( r ); return 0; }
static int generate_key(DH *dh) { int ok=0; int generate_new_key=0; unsigned l; BN_CTX *ctx; BN_MONT_CTX *mont=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; ctx = BN_CTX_new(); if (ctx == NULL) goto err; if (dh->priv_key == NULL) { priv_key=BN_new(); if (priv_key == NULL) goto err; generate_new_key=1; } else priv_key=dh->priv_key; if (dh->pub_key == NULL) { pub_key=BN_new(); if (pub_key == NULL) goto err; } else pub_key=dh->pub_key; if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if (!mont) goto err; } if (generate_new_key) { l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */ if (!BN_rand(priv_key, l, 0, 0)) goto err; } { BIGNUM local_prk; BIGNUM *prk; if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; } dh->pub_key=pub_key; dh->priv_key=priv_key; ok=1; err: if (ok != 1) DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); BN_CTX_free(ctx); return(ok); }
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory", // algorithm 1.5.1). |p| is assumed to be a prime. BIGNUM *ret = in; int err = 1; int r; BIGNUM *A, *b, *q, *t, *x, *y; int e, i, j; if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { if (BN_abs_is_word(p, 2)) { if (ret == NULL) { ret = BN_new(); } if (ret == NULL) { goto end; } if (!BN_set_word(ret, BN_is_bit_set(a, 0))) { if (ret != in) { BN_free(ret); } return NULL; } return ret; } OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); return (NULL); } if (BN_is_zero(a) || BN_is_one(a)) { if (ret == NULL) { ret = BN_new(); } if (ret == NULL) { goto end; } if (!BN_set_word(ret, BN_is_one(a))) { if (ret != in) { BN_free(ret); } return NULL; } return ret; } BN_CTX_start(ctx); A = BN_CTX_get(ctx); b = BN_CTX_get(ctx); q = BN_CTX_get(ctx); t = BN_CTX_get(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); if (y == NULL) { goto end; } if (ret == NULL) { ret = BN_new(); } if (ret == NULL) { goto end; } // A = a mod p if (!BN_nnmod(A, a, p, ctx)) { goto end; } // now write |p| - 1 as 2^e*q where q is odd e = 1; while (!BN_is_bit_set(p, e)) { e++; } // we'll set q later (if needed) if (e == 1) { // The easy case: (|p|-1)/2 is odd, so 2 has an inverse // modulo (|p|-1)/2, and square roots can be computed // directly by modular exponentiation. // We have // 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), // so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. if (!BN_rshift(q, p, 2)) { goto end; } q->neg = 0; if (!BN_add_word(q, 1) || !BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) { goto end; } err = 0; goto vrfy; } if (e == 2) { // |p| == 5 (mod 8) // // In this case 2 is always a non-square since // Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. // So if a really is a square, then 2*a is a non-square. // Thus for // b := (2*a)^((|p|-5)/8), // i := (2*a)*b^2 // we have // i^2 = (2*a)^((1 + (|p|-5)/4)*2) // = (2*a)^((p-1)/2) // = -1; // so if we set // x := a*b*(i-1), // then // x^2 = a^2 * b^2 * (i^2 - 2*i + 1) // = a^2 * b^2 * (-2*i) // = a*(-i)*(2*a*b^2) // = a*(-i)*i // = a. // // (This is due to A.O.L. Atkin, // <URL: //http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>, // November 1992.) // t := 2*a if (!BN_mod_lshift1_quick(t, A, p)) { goto end; } // b := (2*a)^((|p|-5)/8) if (!BN_rshift(q, p, 3)) { goto end; } q->neg = 0; if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) { goto end; } // y := b^2 if (!BN_mod_sqr(y, b, p, ctx)) { goto end; } // t := (2*a)*b^2 - 1 if (!BN_mod_mul(t, t, y, p, ctx) || !BN_sub_word(t, 1)) { goto end; } // x = a*b*t if (!BN_mod_mul(x, A, b, p, ctx) || !BN_mod_mul(x, x, t, p, ctx)) { goto end; } if (!BN_copy(ret, x)) { goto end; } err = 0; goto vrfy; } // e > 2, so we really have to use the Tonelli/Shanks algorithm. // First, find some y that is not a square. if (!BN_copy(q, p)) { goto end; // use 'q' as temp } q->neg = 0; i = 2; do { // For efficiency, try small numbers first; // if this fails, try random numbers. if (i < 22) { if (!BN_set_word(y, i)) { goto end; } } else { if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) { goto end; } if (BN_ucmp(y, p) >= 0) { if (!(p->neg ? BN_add : BN_sub)(y, y, p)) { goto end; } } // now 0 <= y < |p| if (BN_is_zero(y)) { if (!BN_set_word(y, i)) { goto end; } } } r = bn_jacobi(y, q, ctx); // here 'q' is |p| if (r < -1) { goto end; } if (r == 0) { // m divides p OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); goto end; } } while (r == 1 && ++i < 82); if (r != -1) { // Many rounds and still no non-square -- this is more likely // a bug than just bad luck. // Even if p is not prime, we should have found some y // such that r == -1. OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); goto end; } // Here's our actual 'q': if (!BN_rshift(q, q, e)) { goto end; } // Now that we have some non-square, we can find an element // of order 2^e by computing its q'th power. if (!BN_mod_exp_mont(y, y, q, p, ctx, NULL)) { goto end; } if (BN_is_one(y)) { OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); goto end; } // Now we know that (if p is indeed prime) there is an integer // k, 0 <= k < 2^e, such that // // a^q * y^k == 1 (mod p). // // As a^q is a square and y is not, k must be even. // q+1 is even, too, so there is an element // // X := a^((q+1)/2) * y^(k/2), // // and it satisfies // // X^2 = a^q * a * y^k // = a, // // so it is the square root that we are looking for. // t := (q-1)/2 (note that q is odd) if (!BN_rshift1(t, q)) { goto end; } // x := a^((q-1)/2) if (BN_is_zero(t)) // special case: p = 2^e + 1 { if (!BN_nnmod(t, A, p, ctx)) { goto end; } if (BN_is_zero(t)) { // special case: a == 0 (mod p) BN_zero(ret); err = 0; goto end; } else if (!BN_one(x)) { goto end; } } else { if (!BN_mod_exp_mont(x, A, t, p, ctx, NULL)) { goto end; } if (BN_is_zero(x)) { // special case: a == 0 (mod p) BN_zero(ret); err = 0; goto end; } } // b := a*x^2 (= a^q) if (!BN_mod_sqr(b, x, p, ctx) || !BN_mod_mul(b, b, A, p, ctx)) { goto end; } // x := a*x (= a^((q+1)/2)) if (!BN_mod_mul(x, x, A, p, ctx)) { goto end; } while (1) { // Now b is a^q * y^k for some even k (0 <= k < 2^E // where E refers to the original value of e, which we // don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). // // We have a*b = x^2, // y^2^(e-1) = -1, // b^2^(e-1) = 1. if (BN_is_one(b)) { if (!BN_copy(ret, x)) { goto end; } err = 0; goto vrfy; } // find smallest i such that b^(2^i) = 1 i = 1; if (!BN_mod_sqr(t, b, p, ctx)) { goto end; } while (!BN_is_one(t)) { i++; if (i == e) { OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); goto end; } if (!BN_mod_mul(t, t, t, p, ctx)) { goto end; } } // t := y^2^(e - i - 1) if (!BN_copy(t, y)) { goto end; } for (j = e - i - 1; j > 0; j--) { if (!BN_mod_sqr(t, t, p, ctx)) { goto end; } } if (!BN_mod_mul(y, t, t, p, ctx) || !BN_mod_mul(x, x, t, p, ctx) || !BN_mod_mul(b, b, y, p, ctx)) { goto end; } e = i; } vrfy: if (!err) { // verify the result -- the input might have been not a square // (test added in 0.9.8) if (!BN_mod_sqr(x, ret, p, ctx)) { err = 1; } if (!err && 0 != BN_cmp(x, A)) { OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); err = 1; } } end: if (err) { if (ret != in) { BN_clear_free(ret); } ret = NULL; } BN_CTX_end(ctx); return ret; }
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type) { unsigned char *B, *D, *I, *p, *Ai; int Slen, Plen, Ilen, Ijlen; int i, j, u, v; int ret = 0; BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); v = EVP_MD_block_size(md_type); u = EVP_MD_size(md_type); if (u < 0) return 0; D = malloc(v); Ai = malloc(u); B = malloc(v + 1); Slen = v * ((saltlen + v - 1) / v); if (passlen) Plen = v * ((passlen + v - 1)/v); else Plen = 0; Ilen = Slen + Plen; I = malloc(Ilen); Ij = BN_new(); Bpl1 = BN_new(); if (!D || !Ai || !B || !I || !Ij || !Bpl1) goto err; for (i = 0; i < v; i++) D[i] = id; p = I; for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen]; for (i = 0; i < Plen; i++) *p++ = pass[i % passlen]; for (;;) { if (!EVP_DigestInit_ex(&ctx, md_type, NULL) || !EVP_DigestUpdate(&ctx, D, v) || !EVP_DigestUpdate(&ctx, I, Ilen) || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) goto err; for (j = 1; j < iter; j++) { if (!EVP_DigestInit_ex(&ctx, md_type, NULL) || !EVP_DigestUpdate(&ctx, Ai, u) || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) goto err; } memcpy (out, Ai, min (n, u)); if (u >= n) { ret = 1; goto end; } n -= u; out += u; for (j = 0; j < v; j++) B[j] = Ai[j % u]; /* Work out B + 1 first then can use B as tmp space */ if (!BN_bin2bn (B, v, Bpl1)) goto err; if (!BN_add_word (Bpl1, 1)) goto err; for (j = 0; j < Ilen; j += v) { if (!BN_bin2bn(I + j, v, Ij)) goto err; if (!BN_add(Ij, Ij, Bpl1)) goto err; if (!BN_bn2bin(Ij, B)) goto err; Ijlen = BN_num_bytes (Ij); /* If more than 2^(v*8) - 1 cut off MSB */ if (Ijlen > v) { if (!BN_bn2bin (Ij, B)) goto err; memcpy (I + j, B + 1, v); #ifndef PKCS12_BROKEN_KEYGEN /* If less than v bytes pad with zeroes */ } else if (Ijlen < v) { memset(I + j, 0, v - Ijlen); if (!BN_bn2bin(Ij, I + j + v - Ijlen)) goto err; #endif } else if (!BN_bn2bin (Ij, I + j)) goto err; } } err: PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); end: free(Ai); free(B); free(D); free(I); BN_free(Ij); BN_free(Bpl1); EVP_MD_CTX_cleanup(&ctx); return ret; }
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) /* Returns 'ret' such that * ret^2 == a (mod p), * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course * in Algebraic Computational Number Theory", algorithm 1.5.1). * 'p' must be prime! */ { BIGNUM *ret = in; int err = 1; int r; BIGNUM *A, *b, *q, *t, *x, *y; int e, i, j; if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { if (BN_abs_is_word(p, 2)) { if (ret == NULL) ret = BN_new(); if (ret == NULL) goto end; if (!BN_set_word(ret, BN_is_bit_set(a, 0))) { BN_free(ret); return NULL; } bn_check_top(ret); return ret; } BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); return(NULL); } if (BN_is_zero(a) || BN_is_one(a)) { if (ret == NULL) ret = BN_new(); if (ret == NULL) goto end; if (!BN_set_word(ret, BN_is_one(a))) { BN_free(ret); return NULL; } bn_check_top(ret); return ret; } BN_CTX_start(ctx); A = BN_CTX_get(ctx); b = BN_CTX_get(ctx); q = BN_CTX_get(ctx); t = BN_CTX_get(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); if (y == NULL) goto end; if (ret == NULL) ret = BN_new(); if (ret == NULL) goto end; /* A = a mod p */ if (!BN_nnmod(A, a, p, ctx)) goto end; /* now write |p| - 1 as 2^e*q where q is odd */ e = 1; while (!BN_is_bit_set(p, e)) e++; /* we'll set q later (if needed) */ if (e == 1) { /* The easy case: (|p|-1)/2 is odd, so 2 has an inverse * modulo (|p|-1)/2, and square roots can be computed * directly by modular exponentiation. * We have * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. */ if (!BN_rshift(q, p, 2)) goto end; q->neg = 0; if (!BN_add_word(q, 1)) goto end; if (!BN_mod_exp(ret, A, q, p, ctx)) goto end; err = 0; goto vrfy; } if (e == 2) { /* |p| == 5 (mod 8) * * In this case 2 is always a non-square since * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. * So if a really is a square, then 2*a is a non-square. * Thus for * b := (2*a)^((|p|-5)/8), * i := (2*a)*b^2 * we have * i^2 = (2*a)^((1 + (|p|-5)/4)*2) * = (2*a)^((p-1)/2) * = -1; * so if we set * x := a*b*(i-1), * then * x^2 = a^2 * b^2 * (i^2 - 2*i + 1) * = a^2 * b^2 * (-2*i) * = a*(-i)*(2*a*b^2) * = a*(-i)*i * = a. * * (This is due to A.O.L. Atkin, * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>, * November 1992.) */ /* t := 2*a */ if (!BN_mod_lshift1_quick(t, A, p)) goto end; /* b := (2*a)^((|p|-5)/8) */ if (!BN_rshift(q, p, 3)) goto end; q->neg = 0; if (!BN_mod_exp(b, t, q, p, ctx)) goto end; /* y := b^2 */ if (!BN_mod_sqr(y, b, p, ctx)) goto end; /* t := (2*a)*b^2 - 1*/ if (!BN_mod_mul(t, t, y, p, ctx)) goto end; if (!BN_sub_word(t, 1)) goto end; /* x = a*b*t */ if (!BN_mod_mul(x, A, b, p, ctx)) goto end; if (!BN_mod_mul(x, x, t, p, ctx)) goto end; if (!BN_copy(ret, x)) goto end; err = 0; goto vrfy; } /* e > 2, so we really have to use the Tonelli/Shanks algorithm. * First, find some y that is not a square. */ if (!BN_copy(q, p)) goto end; /* use 'q' as temp */ q->neg = 0; i = 2; do { /* For efficiency, try small numbers first; * if this fails, try random numbers. */ if (i < 22) { if (!BN_set_word(y, i)) goto end; } else { if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end; if (BN_ucmp(y, p) >= 0) { if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end; } /* now 0 <= y < |p| */ if (BN_is_zero(y)) if (!BN_set_word(y, i)) goto end; } r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */ if (r < -1) goto end; if (r == 0) { /* m divides p */ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); goto end; } } while (r == 1 && ++i < 82); if (r != -1) { /* Many rounds and still no non-square -- this is more likely * a bug than just bad luck. * Even if p is not prime, we should have found some y * such that r == -1. */ BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); goto end; } /* Here's our actual 'q': */ if (!BN_rshift(q, q, e)) goto end; /* Now that we have some non-square, we can find an element * of order 2^e by computing its q'th power. */ if (!BN_mod_exp(y, y, q, p, ctx)) goto end; if (BN_is_one(y)) { BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); goto end; } /* Now we know that (if p is indeed prime) there is an integer * k, 0 <= k < 2^e, such that * * a^q * y^k == 1 (mod p). * * As a^q is a square and y is not, k must be even. * q+1 is even, too, so there is an element * * X := a^((q+1)/2) * y^(k/2), * * and it satisfies * * X^2 = a^q * a * y^k * = a, * * so it is the square root that we are looking for. */ /* t := (q-1)/2 (note that q is odd) */ if (!BN_rshift1(t, q)) goto end; /* x := a^((q-1)/2) */ if (BN_is_zero(t)) /* special case: p = 2^e + 1 */ { if (!BN_nnmod(t, A, p, ctx)) goto end; if (BN_is_zero(t)) { /* special case: a == 0 (mod p) */ BN_zero(ret); err = 0; goto end; } else if (!BN_one(x)) goto end; } else { if (!BN_mod_exp(x, A, t, p, ctx)) goto end; if (BN_is_zero(x)) { /* special case: a == 0 (mod p) */ BN_zero(ret); err = 0; goto end; } } /* b := a*x^2 (= a^q) */ if (!BN_mod_sqr(b, x, p, ctx)) goto end; if (!BN_mod_mul(b, b, A, p, ctx)) goto end; /* x := a*x (= a^((q+1)/2)) */ if (!BN_mod_mul(x, x, A, p, ctx)) goto end; while (1) { /* Now b is a^q * y^k for some even k (0 <= k < 2^E * where E refers to the original value of e, which we * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). * * We have a*b = x^2, * y^2^(e-1) = -1, * b^2^(e-1) = 1. */ if (BN_is_one(b)) { if (!BN_copy(ret, x)) goto end; err = 0; goto vrfy; } /* find smallest i such that b^(2^i) = 1 */ i = 1; if (!BN_mod_sqr(t, b, p, ctx)) goto end; while (!BN_is_one(t)) { i++; if (i == e) { BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); goto end; } if (!BN_mod_mul(t, t, t, p, ctx)) goto end; } /* t := y^2^(e - i - 1) */ if (!BN_copy(t, y)) goto end; for (j = e - i - 1; j > 0; j--) { if (!BN_mod_sqr(t, t, p, ctx)) goto end; } if (!BN_mod_mul(y, t, t, p, ctx)) goto end; if (!BN_mod_mul(x, x, t, p, ctx)) goto end; if (!BN_mod_mul(b, b, y, p, ctx)) goto end; e = i; } vrfy: if (!err) { /* verify the result -- the input might have been not a square * (test added in 0.9.8) */ if (!BN_mod_sqr(x, ret, p, ctx)) err = 1; if (!err && 0 != BN_cmp(x, A)) { BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); err = 1; } } end: if (err) { if (ret != NULL && ret != in) { BN_clear_free(ret); } ret = NULL; } BN_CTX_end(ctx); bn_check_top(ret); return ret; }
/* * rsa_get_params(): - Get the important parameters of an RSA public key */ int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp, BIGNUM **modulusp, BIGNUM **r_squaredp) { BIGNUM *big1, *big2, *big32, *big2_32; BIGNUM *n, *r, *r_squared, *tmp; BN_CTX *bn_ctx = BN_CTX_new(); int ret = 0; /* Initialize BIGNUMs */ big1 = BN_new(); big2 = BN_new(); big32 = BN_new(); r = BN_new(); r_squared = BN_new(); tmp = BN_new(); big2_32 = BN_new(); n = BN_new(); if (!big1 || !big2 || !big32 || !r || !r_squared || !tmp || !big2_32 || !n) { fprintf(stderr, "Out of memory (bignum)\n"); return -ENOMEM; } if (0 != rsa_get_exponent(key, exponent)) ret = -1; if (!BN_copy(n, key->n) || !BN_set_word(big1, 1L) || !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L)) ret = -1; /* big2_32 = 2^32 */ if (!BN_exp(big2_32, big2, big32, bn_ctx)) ret = -1; /* Calculate n0_inv = -1 / n[0] mod 2^32 */ if (!BN_mod_inverse(tmp, n, big2_32, bn_ctx) || !BN_sub(tmp, big2_32, tmp)) ret = -1; *n0_invp = BN_get_word(tmp); /* Calculate R = 2^(# of key bits) */ if (!BN_set_word(tmp, BN_num_bits(n)) || !BN_exp(r, big2, tmp, bn_ctx)) ret = -1; /* Calculate r_squared = R^2 mod n */ if (!BN_copy(r_squared, r) || !BN_mul(tmp, r_squared, r, bn_ctx) || !BN_mod(r_squared, tmp, n, bn_ctx)) ret = -1; *modulusp = n; *r_squaredp = r_squared; BN_free(big1); BN_free(big2); BN_free(big32); BN_free(r); BN_free(tmp); BN_free(big2_32); if (ret) { fprintf(stderr, "Bignum operations failed\n"); return -ENOMEM; } return ret; }
int rsa_add_verify_data(struct image_sign_info *info, void *keydest) { BIGNUM *modulus, *r_squared; uint64_t exponent; uint32_t n0_inv; int parent, node; char name[100]; int ret; int bits; RSA *rsa; debug("%s: Getting verification data\n", __func__); ret = rsa_get_pub_key(info->keydir, info->keyname, &rsa); if (ret) return ret; ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared); if (ret) return ret; bits = BN_num_bits(modulus); parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME); if (parent == -FDT_ERR_NOTFOUND) { parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME); if (parent < 0) { ret = parent; if (ret != -FDT_ERR_NOSPACE) { fprintf(stderr, "Couldn't create signature node: %s\n", fdt_strerror(parent)); } } } if (ret) goto done; /* Either create or overwrite the named key node */ snprintf(name, sizeof(name), "key-%s", info->keyname); node = fdt_subnode_offset(keydest, parent, name); if (node == -FDT_ERR_NOTFOUND) { node = fdt_add_subnode(keydest, parent, name); if (node < 0) { ret = node; if (ret != -FDT_ERR_NOSPACE) { fprintf(stderr, "Could not create key subnode: %s\n", fdt_strerror(node)); } } } else if (node < 0) { fprintf(stderr, "Cannot select keys parent: %s\n", fdt_strerror(node)); ret = node; } if (!ret) { ret = fdt_setprop_string(keydest, node, "key-name-hint", info->keyname); } if (!ret) ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits); if (!ret) ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv); if (!ret) { ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent); } if (!ret) { ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus, bits); } if (!ret) { ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared, bits); } if (!ret) { ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP, info->algo->name); } if (!ret && info->require_keys) { ret = fdt_setprop_string(keydest, node, "required", info->require_keys); } done: BN_free(modulus); BN_free(r_squared); if (ret) return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO; return 0; }
void rdssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus, uint8 * exponent) { #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) BN_CTX *ctx; BIGNUM *mod, *exp, *x, *y; uint8 inr[SEC_MAX_MODULUS_SIZE]; int outlen; reverse(modulus, modulus_size); reverse(exponent, SEC_EXPONENT_SIZE); memcpy(inr, in, len); reverse(inr, len); ctx = BN_CTX_new(); mod = BN_new(); exp = BN_new(); x = BN_new(); y = BN_new(); BN_bin2bn(modulus, modulus_size, mod); BN_bin2bn(exponent, SEC_EXPONENT_SIZE, exp); BN_bin2bn(inr, len, x); BN_mod_exp(y, x, exp, mod, ctx); outlen = BN_bn2bin(y, out); reverse(out, outlen); if (outlen < (int) modulus_size) memset(out + outlen, 0, modulus_size - outlen); BN_free(y); BN_clear_free(x); BN_free(exp); BN_free(mod); BN_CTX_free(ctx); #else /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */ BN_CTX *ctx; BIGNUM mod, exp, x, y; uint8 inr[SEC_MAX_MODULUS_SIZE]; int outlen; reverse(modulus, modulus_size); reverse(exponent, SEC_EXPONENT_SIZE); memcpy(inr, in, len); reverse(inr, len); ctx = BN_CTX_new(); BN_init(&mod); BN_init(&exp); BN_init(&x); BN_init(&y); BN_bin2bn(modulus, modulus_size, &mod); BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp); BN_bin2bn(inr, len, &x); BN_mod_exp(&y, &x, &exp, &mod, ctx); outlen = BN_bn2bin(&y, out); reverse(out, outlen); if (outlen < (int) modulus_size) memset(out + outlen, 0, modulus_size - outlen); BN_free(&y); BN_clear_free(&x); BN_free(&exp); BN_free(&mod); BN_CTX_free(ctx); #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */ }
static int test_ecdh_curve(int nid, BN_CTX *ctx, BIO *out) { EC_KEY *a = NULL; EC_KEY *b = NULL; BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; char buf[12]; unsigned char *abuf = NULL, *bbuf = NULL; int i, alen, blen, aout, bout, ret = 0; const EC_GROUP *group; a = EC_KEY_new_by_curve_name(nid); b = EC_KEY_new_by_curve_name(nid); if (a == NULL || b == NULL) goto err; group = EC_KEY_get0_group(a); if ((x_a = BN_new()) == NULL) goto err; if ((y_a = BN_new()) == NULL) goto err; if ((x_b = BN_new()) == NULL) goto err; if ((y_b = BN_new()) == NULL) goto err; BIO_puts(out, "Testing key generation with "); BIO_puts(out, OBJ_nid2sn(nid)); # ifdef NOISY BIO_puts(out, "\n"); # else (void)BIO_flush(out); # endif if (!EC_KEY_generate_key(a)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } # ifndef OPENSSL_NO_EC2M else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } # endif # ifdef NOISY BIO_puts(out, " pri 1="); BN_print(out, a->priv_key); BIO_puts(out, "\n pub 1="); BN_print(out, x_a); BIO_puts(out, ","); BN_print(out, y_a); BIO_puts(out, "\n"); # else BIO_printf(out, " ."); (void)BIO_flush(out); # endif if (!EC_KEY_generate_key(b)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } # ifndef OPENSSL_NO_EC2M else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } # endif # ifdef NOISY BIO_puts(out, " pri 2="); BN_print(out, b->priv_key); BIO_puts(out, "\n pub 2="); BN_print(out, x_b); BIO_puts(out, ","); BN_print(out, y_b); BIO_puts(out, "\n"); # else BIO_printf(out, "."); (void)BIO_flush(out); # endif alen = KDF1_SHA1_len; abuf = OPENSSL_malloc(alen); aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1); # ifdef NOISY BIO_puts(out, " key1 ="); for (i = 0; i < aout; i++) { sprintf(buf, "%02X", abuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); # else BIO_printf(out, "."); (void)BIO_flush(out); # endif blen = KDF1_SHA1_len; bbuf = OPENSSL_malloc(blen); bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1); # ifdef NOISY BIO_puts(out, " key2 ="); for (i = 0; i < bout; i++) { sprintf(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); # else BIO_printf(out, "."); (void)BIO_flush(out); # endif if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { # ifndef NOISY BIO_printf(out, " failed\n\n"); BIO_printf(out, "key a:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(a)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_a); BIO_printf(out, ","); BN_print(out, y_a); BIO_printf(out, "\nkey b:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(b)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_b); BIO_printf(out, ","); BN_print(out, y_b); BIO_printf(out, "\n"); BIO_printf(out, "generated key a: "); for (i = 0; i < bout; i++) { sprintf(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_printf(out, "\n"); BIO_printf(out, "generated key b: "); for (i = 0; i < aout; i++) { sprintf(buf, "%02X", abuf[i]); BIO_puts(out, buf); } BIO_printf(out, "\n"); # endif fprintf(stderr, "Error in ECDH routines\n"); ret = 0; } else { # ifndef NOISY BIO_printf(out, " ok\n"); # endif ret = 1; } err: ERR_print_errors_fp(stderr); OPENSSL_free(abuf); OPENSSL_free(bbuf); BN_free(x_a); BN_free(y_a); BN_free(x_b); BN_free(y_b); EC_KEY_free(b); EC_KEY_free(a); return (ret); }
void Server::handshake(const char *_I, BIGNUM *A, BIGNUM **B, uint32_t *_salt) { if (I && _I && strcmp(I, _I) == 0) { BIGNUM *b = NULL; BIGNUM *kv = NULL; BIGNUM *u = NULL; BIGNUM *vu = NULL; BIGNUM *Avu = NULL; BIGNUM *S = NULL; unsigned char uH[SHA256_HASH_LEN]; unsigned char K[SHA256_HASH_LEN]; unsigned char *bn_bin1 = NULL; unsigned char *bn_bin2 = NULL; unsigned char *bn_bin3 = NULL; BN_CTX *ctx = NULL; SHA256_CTX sha_ctx; uint32_t md_len = 0; if (!N || !g || !k || !v || !P || !A) goto err; // S->C // Send salt, B=kv + g**b % N if (!(b = BN_new())) goto err; if (!BN_rand_range(b, N)) goto err; if (!(*B = BN_new())) goto err; if (!(ctx = BN_CTX_new())) goto err; if (!BN_mod_exp(*B, g, b, N, ctx)) goto err; if (!(kv = BN_new())) goto err; if (!BN_mul(kv, k, v, ctx)) goto err; if (!BN_add(*B, kv, *B)) goto err; // S, C // Compute string uH = SHA256(A|B), u = integer of uH bn_bin1 = new unsigned char[BN_num_bytes(A)]; BN_bn2bin(A, bn_bin1); bn_bin2 = new unsigned char[BN_num_bytes(*B)]; BN_bn2bin(*B, bn_bin2); if (!SHA256_Init(&sha_ctx)) goto err; if (!SHA256_Update(&sha_ctx, bn_bin1, BN_num_bytes(A))) goto err; if (!SHA256_Update(&sha_ctx, bn_bin2, BN_num_bytes(*B))) goto err; if (!SHA256_Final(uH, &sha_ctx)) goto err; if (!(u = BN_new())) goto err; if (!BN_bin2bn(uH, SHA256_HASH_LEN, u)) goto err; // S // Generate S = (A * v**u) ** b % N // Generate K = SHA256(S) if (!(vu = BN_new())) goto err; if (!BN_mod_exp(vu, v, u, N, ctx)) goto err; if (!(Avu = BN_new())) goto err; if (!BN_mul(Avu, A, vu, ctx)) goto err; if (!(S = BN_new())) goto err; if (!BN_mod_exp(S, Avu, b, N, ctx)) goto err; bn_bin3 = new unsigned char[BN_num_bytes(S)]; BN_bn2bin(S, bn_bin3); if (!SHA256_Init(&sha_ctx)) goto err; if (!SHA256_Update(&sha_ctx, bn_bin3, BN_num_bytes(S))) goto err; if (!SHA256_Final(K, &sha_ctx)) goto err; hmac = new unsigned char[SHA256_HASH_LEN]; hmac = HMAC(EVP_sha256(), K, SHA256_HASH_LEN, (unsigned char *)(&salt), sizeof salt, hmac, &md_len); *_salt = salt; err: if (b) BN_free(b); if (kv) BN_free(kv); if (u) BN_free(u); if (S) BN_free(S); if (vu) BN_free(vu); if (Avu) BN_free(Avu); if (ctx) BN_CTX_free(ctx); if (bn_bin1) delete [] bn_bin1; if (bn_bin2) delete [] bn_bin2; if (bn_bin3) delete [] bn_bin3; } }
static struct wpabuf * eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct wpabuf *resp = NULL; BIGNUM *x = NULL, *y = NULL; HMAC_CTX ctx; u32 cs; u16 grp; u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr; /* * first build up the ciphersuite which is group | random_function | * prf */ grp = htons(data->group_num); ptr = (u8 *) &cs; os_memcpy(ptr, &grp, sizeof(u16)); ptr += sizeof(u16); *ptr = EAP_PWD_DEFAULT_RAND_FUNC; ptr += sizeof(u8); *ptr = EAP_PWD_DEFAULT_PRF; /* each component of the cruft will be at most as big as the prime */ if (((cruft = os_malloc(BN_num_bytes(data->grp->prime))) == NULL) || ((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (server): debug allocation " "fail"); goto fin; } /* * server's commit is H(k | server_element | server_scalar | * peer_element | peer_scalar | ciphersuite) */ H_Init(&ctx); /* * zero the memory each time because this is mod prime math and some * value may start with a few zeros and the previous one did not. */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->k, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* server element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->server_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (server): confirm point " "assignment fail"); goto fin; } os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(x, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(y, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* server scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->server_scalar, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); /* my element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->my_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (server): confirm point " "assignment fail"); goto fin; } os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(x, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(y, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* my scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->my_scalar, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); /* the ciphersuite */ H_Update(&ctx, (u8 *) &cs, sizeof(u32)); /* random function fin */ H_Final(&ctx, conf); ptr = (u8 *) payload; if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm did not verify"); goto fin; } wpa_printf(MSG_DEBUG, "EAP-pwd (peer): confirm verified"); /* * compute confirm: * H(k | peer_element | peer_scalar | server_element | server_scalar | * ciphersuite) */ H_Init(&ctx); /* k */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->k, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* my element */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->my_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm point " "assignment fail"); goto fin; } os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(x, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(y, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* my scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->my_scalar, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); /* server element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->server_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm point " "assignment fail"); goto fin; } os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(x, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(y, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); /* server scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); BN_bn2bin(data->server_scalar, cruft); H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); /* the ciphersuite */ H_Update(&ctx, (u8 *) &cs, sizeof(u32)); /* all done */ H_Final(&ctx, conf); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, sizeof(struct eap_pwd_hdr) + SHA256_DIGEST_LENGTH, EAP_CODE_RESPONSE, eap_get_id(reqData)); if (resp == NULL) goto fin; wpabuf_put_u8(resp, EAP_PWD_OPCODE_CONFIRM_EXCH); wpabuf_put_data(resp, conf, SHA256_DIGEST_LENGTH); if (compute_keys(data->grp, data->bnctx, data->k, data->my_scalar, data->server_scalar, conf, ptr, &cs, data->msk, data->emsk) < 0) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute MSK | " "EMSK"); goto fin; } fin: os_free(cruft); BN_free(x); BN_free(y); ret->methodState = METHOD_DONE; if (resp == NULL) { ret->decision = DECISION_FAIL; eap_pwd_state(data, FAILURE); } else { ret->decision = DECISION_UNCOND_SUCC; eap_pwd_state(data, SUCCESS); } return resp; }
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *kinv=NULL,*r=NULL,*s=NULL; BIGNUM m; BIGNUM xr; BN_CTX *ctx=NULL; int i,reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; BN_init(&m); BN_init(&xr); if (!dsa->p || !dsa->q || !dsa->g) { reason=DSA_R_MISSING_PARAMETERS; goto err; } s=BN_new(); if (s == NULL) goto err; i=BN_num_bytes(dsa->q); /* should be 20 */ if ((dlen > i) || (dlen > 50)) { reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; goto err; } ctx=BN_CTX_new(); if (ctx == NULL) goto err; if ((dsa->kinv == NULL) || (dsa->r == NULL)) { if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; } else { kinv=dsa->kinv; dsa->kinv=NULL; r=dsa->r; dsa->r=NULL; } if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; /* Compute s = inv(k) (m + xr) mod q */ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ if (BN_cmp(s,dsa->q) > 0) BN_sub(s,s,dsa->q); if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; ret=DSA_SIG_new(); if (ret == NULL) goto err; ret->r = r; ret->s = s; err: if (!ret) { DSAerr(DSA_F_DSA_DO_SIGN,reason); BN_free(r); BN_free(s); } if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&m); BN_clear_free(&xr); if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ BN_clear_free(kinv); return(ret); }
int EC_KEY_generate_key(EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; BIGNUM *priv_key = NULL, *order = NULL; EC_POINT *pub_key = NULL; if (!eckey || !eckey->group) { ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((order = BN_new()) == NULL) goto err; if ((ctx = BN_CTX_new()) == NULL) goto err; if (eckey->priv_key == NULL) { priv_key = BN_new(); if (priv_key == NULL) goto err; } else priv_key = eckey->priv_key; if (!EC_GROUP_get_order(eckey->group, order, ctx)) goto err; do if (!BN_rand_range(priv_key, order)) goto err; while (BN_is_zero(priv_key)); if (eckey->pub_key == NULL) { pub_key = EC_POINT_new(eckey->group); if (pub_key == NULL) goto err; } else pub_key = eckey->pub_key; if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) goto err; eckey->priv_key = priv_key; eckey->pub_key = pub_key; ok=1; err: if (order) BN_free(order); if (pub_key != NULL && eckey->pub_key == NULL) EC_POINT_free(pub_key); if (priv_key != NULL && eckey->priv_key == NULL) BN_free(priv_key); if (ctx != NULL) BN_CTX_free(ctx); return(ok); }
static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { BN_CTX *ctx; BIGNUM u1,u2,t1; BN_MONT_CTX *mont=NULL; int ret = -1; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); return -1; } if (BN_num_bits(dsa->q) != 160) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); return -1; } if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); return -1; } BN_init(&u1); BN_init(&u2); BN_init(&t1); if ((ctx=BN_CTX_new()) == NULL) goto err; if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, dsa->q) >= 0) { ret = 0; goto err; } if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, dsa->q) >= 0) { ret = 0; goto err; } /* Calculate W = inv(S) mod Q * save W in u2 */ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; /* save M in u1 */ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; /* u1 = M * w mod q */ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; /* u2 = r * w mod q */ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, CRYPTO_LOCK_DSA, dsa->p, ctx); if (!mont) goto err; } DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont); /* BN_copy(&u1,&t1); */ /* let u1 = u1 mod q */ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; /* V is now in u1. If the signature is correct, it will be * equal to R. */ ret=(BN_ucmp(&u1, sig->r) == 0); err: /* XXX: surely this is wrong - if ret is 0, it just didn't verify; there is no error in BN. Test should be ret == -1 (Ben) */ if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); if (ctx != NULL) BN_CTX_free(ctx); BN_free(&u1); BN_free(&u2); BN_free(&t1); return(ret); }
static void bexp(void) { struct number *a, *p; struct number *r; bool neg; u_int scale; p = pop_number(); if (p == NULL) { return; } a = pop_number(); if (a == NULL) { push_number(p); return; } if (p->scale != 0) warnx("Runtime warning: non-zero scale in exponent"); normalize(p, 0); neg = false; if (BN_cmp(p->number, &zero) < 0) { neg = true; negate(p); scale = bmachine.scale; } else { /* Posix bc says min(a.scale * b, max(a.scale, scale) */ u_long b; u_int m; b = BN_get_word(p->number); m = max(a->scale, bmachine.scale); scale = a->scale * (u_int)b; if (scale > m || (a->scale > 0 && (b == BN_MASK2 || b > UINT_MAX))) scale = m; } if (BN_is_zero(p->number)) { r = new_number(); bn_check(BN_one(r->number)); normalize(r, scale); } else { while (!BN_is_bit_set(p->number, 0)) { bmul_number(a, a, a); bn_check(BN_rshift1(p->number, p->number)); } r = dup_number(a); normalize(r, scale); bn_check(BN_rshift1(p->number, p->number)); while (!BN_is_zero(p->number)) { bmul_number(a, a, a); if (BN_is_bit_set(p->number, 0)) bmul_number(r, r, a); bn_check(BN_rshift1(p->number, p->number)); } if (neg) { BN_CTX *ctx; BIGNUM *one; one = BN_new(); bn_checkp(one); bn_check(BN_one(one)); ctx = BN_CTX_new(); bn_checkp(ctx); scale_number(one, r->scale + scale); normalize(r, scale); bn_check(BN_div(r->number, NULL, one, r->number, ctx)); BN_free(one); BN_CTX_free(ctx); } else normalize(r, scale); } push_number(r); free_number(a); free_number(p); }
static int run_srp(const char *username, const char *client_pass, const char *server_pass) { int ret = -1; BIGNUM *s = NULL; BIGNUM *v = NULL; BIGNUM *a = NULL; BIGNUM *b = NULL; BIGNUM *u = NULL; BIGNUM *x = NULL; BIGNUM *Apub = NULL; BIGNUM *Bpub = NULL; BIGNUM *Kclient = NULL; BIGNUM *Kserver = NULL; unsigned char rand_tmp[RANDOM_SIZE]; /* use builtin 1024-bit params */ const SRP_gN *GN = SRP_get_default_gN("1024"); if (GN == NULL) { fprintf(stderr, "Failed to get SRP parameters\n"); return -1; } /* Set up server's password entry */ if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) { fprintf(stderr, "Failed to create SRP verifier\n"); return -1; } showbn("N", GN->N); showbn("g", GN->g); showbn("Salt", s); showbn("Verifier", v); /* Server random */ RAND_bytes(rand_tmp, sizeof(rand_tmp)); b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); /* TODO - check b != 0 */ showbn("b", b); /* Server's first message */ Bpub = SRP_Calc_B(b, GN->N, GN->g, v); showbn("B", Bpub); if (!SRP_Verify_B_mod_N(Bpub, GN->N)) { fprintf(stderr, "Invalid B\n"); return -1; } /* Client random */ RAND_bytes(rand_tmp, sizeof(rand_tmp)); a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); /* TODO - check a != 0 */ showbn("a", a); /* Client's response */ Apub = SRP_Calc_A(a, GN->N, GN->g); showbn("A", Apub); if (!SRP_Verify_A_mod_N(Apub, GN->N)) { fprintf(stderr, "Invalid A\n"); return -1; } /* Both sides calculate u */ u = SRP_Calc_u(Apub, Bpub, GN->N); /* Client's key */ x = SRP_Calc_x(s, username, client_pass); Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); showbn("Client's key", Kclient); /* Server's key */ Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); showbn("Server's key", Kserver); if (BN_cmp(Kclient, Kserver) == 0) { ret = 0; } else { fprintf(stderr, "Keys mismatch\n"); ret = 1; } BN_clear_free(Kclient); BN_clear_free(Kserver); BN_clear_free(x); BN_free(u); BN_free(Apub); BN_clear_free(a); BN_free(Bpub); BN_clear_free(b); BN_free(s); BN_clear_free(v); 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 (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || (p1 == RSA_PKCS1_PSS_PADDING && 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || (p1 == RSA_PKCS1_OAEP_PADDING && 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && rctx->md == NULL) { rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; 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) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN); return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { *(int *)p2 = rctx->saltlen; } else { if (p1 < -2) { return 0; } rctx->saltlen = p1; } return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS); return 0; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) { return 0; } 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) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } 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) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD); return 0; } 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) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } if (rctx->oaep_label) { OPENSSL_free(rctx->oaep_label); } if (p2 && p1 > 0) { /* TODO(fork): this seems wrong. Shouldn't it take a copy of the * buffer? */ 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) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); return 1; case EVP_PKEY_CTRL_DIGESTINIT: return 1; default: OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); return 0; } }
int prime_main(int argc, char **argv) { int hex = 0; int checks = 20; int generate = 0; int bits = 0; int safe = 0; BIGNUM *bn = NULL; BIO *bio_out; --argc; ++argv; while (argc >= 1 && **argv == '-') { if (!strcmp(*argv, "-hex")) hex = 1; else if (!strcmp(*argv, "-generate")) generate = 1; else if (!strcmp(*argv, "-bits")) if (--argc < 1) goto bad; else bits = atoi(*++argv); else if (!strcmp(*argv, "-safe")) safe = 1; else if (!strcmp(*argv, "-checks")) if (--argc < 1) goto bad; else checks = atoi(*++argv); else { BIO_printf(bio_err, "Unknown option '%s'\n", *argv); goto bad; } --argc; ++argv; } if (argv[0] == NULL && !generate) { BIO_printf(bio_err, "No prime specified\n"); goto bad; } if ((bio_out = BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); } if (generate) { char *s; if (!bits) { BIO_printf(bio_err, "Specifiy the number of bits.\n"); return 1; } bn = BN_new(); BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL); s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); BIO_printf(bio_out, "%s\n", s); free(s); } else { if (hex) BN_hex2bn(&bn, argv[0]); else BN_dec2bn(&bn, argv[0]); BN_print(bio_out, bn); BIO_printf(bio_out, " is %sprime\n", BN_is_prime_ex(bn, checks, NULL, NULL) ? "" : "not "); } BN_free(bn); BIO_free_all(bio_out); return 0; bad: BIO_printf(bio_err, "options are\n"); BIO_printf(bio_err, "%-14s hex\n", "-hex"); BIO_printf(bio_err, "%-14s number of checks\n", "-checks <n>"); return 1; }
BigNumber::~BigNumber() { BN_free(_bn); delete[] _array; }
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; }
int RSA_set_RSAPRIVATEKEYBLOB(RSA *rsa, const RSAPRIVATEKEYBLOB *blob) { int ret = 0; BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; BIGNUM *p = NULL; BIGNUM *q = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; BIGNUM *iqmp = NULL; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (blob->AlgID != SGD_RSA) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_ALGOR); return 0; } if (blob->BitLen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS || blob->BitLen > sizeof(blob->Modulus) * 8 || blob->BitLen % 8 != 0 || blob->BitLen % 16 != 0) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!(n = BN_bin2bn(blob->Modulus, sizeof(blob->Modulus), NULL)) || !(e = BN_bin2bn(blob->PublicExponent, sizeof(blob->PublicExponent), NULL)) || !(d = BN_bin2bn(blob->PrivateExponent, sizeof(blob->PrivateExponent), NULL)) || !(p = BN_bin2bn(blob->Prime1, sizeof(blob->Prime1), NULL)) || !(q = BN_bin2bn(blob->Prime2, sizeof(blob->Prime2), NULL)) || !(dmp1 = BN_bin2bn(blob->Prime1Exponent, sizeof(blob->Prime1Exponent), NULL)) || !(dmq1 = BN_bin2bn(blob->Prime2Exponent, sizeof(blob->Prime2Exponent), NULL)) || !(iqmp = BN_bin2bn(blob->Coefficient, sizeof(blob->Coefficient), NULL))) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_BN_LIB); goto end; } if (!RSA_set0_key(rsa, n, e, d)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } n = NULL; e = NULL; d = NULL; if (!RSA_set0_factors(rsa, p, q)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } p = NULL; q = NULL; if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } dmp1 = NULL; dmq1 = NULL; iqmp = NULL; ret = 1; end: BN_free(n); BN_free(e); BN_free(d); BN_free(p); BN_free(q); BN_free(dmp1); BN_free(dmq1); BN_free(iqmp); return ret; }
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */ DH *dh_params = NULL; int mpint; /* 0 or 4 */ { ERL_NIF_TERM head, tail; BIGNUM *dh_p = NULL, *dh_g = NULL, *priv_key_in = NULL; unsigned long len = 0; if (!(get_bn_from_bin(env, argv[0], &priv_key_in) || argv[0] == atom_undefined) || !enif_get_list_cell(env, argv[1], &head, &tail) || !get_bn_from_bin(env, head, &dh_p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dh_g) || !enif_is_empty_list(env, tail) || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4) || !enif_get_ulong(env, argv[3], &len) /* Load dh_params with values to use by the generator. Mem mgmnt transfered from dh_p etc to dh_params */ || !(dh_params = DH_new()) || (priv_key_in && !DH_set0_key(dh_params, NULL, priv_key_in)) || !DH_set0_pqg(dh_params, dh_p, NULL, dh_g) ) { if (priv_key_in) BN_free(priv_key_in); if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (dh_params) DH_free(dh_params); return enif_make_badarg(env); } if (len) { if (len < BN_num_bits(dh_p)) DH_set_length(dh_params, len); else { if (priv_key_in) BN_free(priv_key_in); if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (dh_params) DH_free(dh_params); return enif_make_badarg(env); } } } #ifdef HAS_EVP_PKEY_CTX { EVP_PKEY_CTX *ctx; EVP_PKEY *dhkey, *params; int success; params = EVP_PKEY_new(); success = EVP_PKEY_set1_DH(params, dh_params); /* set the key referenced by params to dh_params... */ DH_free(dh_params); /* ...dh_params (and params) must be freed */ if (!success) return atom_error; ctx = EVP_PKEY_CTX_new(params, NULL); EVP_PKEY_free(params); if (!ctx) { return atom_error; } if (!EVP_PKEY_keygen_init(ctx)) { /* EVP_PKEY_CTX_free(ctx); */ return atom_error; } dhkey = EVP_PKEY_new(); if (!EVP_PKEY_keygen(ctx, &dhkey)) { /* "performs a key generation operation, the ... */ /*... generated key is written to ppkey." (=last arg) */ /* EVP_PKEY_CTX_free(ctx); */ /* EVP_PKEY_free(dhkey); */ return atom_error; } dh_params = EVP_PKEY_get1_DH(dhkey); /* return the referenced key. dh_params and dhkey must be freed */ EVP_PKEY_free(dhkey); if (!dh_params) { /* EVP_PKEY_CTX_free(ctx); */ return atom_error; } EVP_PKEY_CTX_free(ctx); } #else if (!DH_generate_key(dh_params)) return atom_error; #endif { unsigned char *pub_ptr, *prv_ptr; int pub_len, prv_len; ERL_NIF_TERM ret_pub, ret_prv; const BIGNUM *pub_key_gen, *priv_key_gen; DH_get0_key(dh_params, &pub_key_gen, &priv_key_gen); /* Get pub_key_gen and priv_key_gen. "The values point to the internal representation of the public key and private key values. This memory should not be freed directly." says man */ pub_len = BN_num_bytes(pub_key_gen); prv_len = BN_num_bytes(priv_key_gen); pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub); prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv); if (mpint) { put_int32(pub_ptr, pub_len); pub_ptr += 4; put_int32(prv_ptr, prv_len); prv_ptr += 4; } BN_bn2bin(pub_key_gen, pub_ptr); BN_bn2bin(priv_key_gen, prv_ptr); ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len); ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len); DH_free(dh_params); return enif_make_tuple2(env, ret_pub, ret_prv); } }
void YAK_STEP_PART_release(YAK_STEP_PART *p) { YAK_ZKP_release(&p->zkpx); BN_free(p->gk); }
static struct wpabuf * eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct wpabuf *resp = NULL; EC_POINT *K = NULL, *point = NULL; BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL; u16 offset; u8 *ptr, *scalar = NULL, *element = NULL; if (((data->private_value = BN_new()) == NULL) || ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) || ((cofactor = BN_new()) == NULL) || ((data->my_scalar = BN_new()) == NULL) || ((mask = BN_new()) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail"); goto fin; } if (!EC_GROUP_get_cofactor(data->grp->group, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor " "for curve"); goto fin; } BN_rand_range(data->private_value, data->grp->order); BN_rand_range(mask, data->grp->order); BN_add(data->my_scalar, data->private_value, mask); BN_mod(data->my_scalar, data->my_scalar, data->grp->order, data->bnctx); if (!EC_POINT_mul(data->grp->group, data->my_element, NULL, data->grp->pwe, mask, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): element allocation " "fail"); eap_pwd_state(data, FAILURE); goto fin; } if (!EC_POINT_invert(data->grp->group, data->my_element, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): element inversion fail"); goto fin; } BN_free(mask); if (((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): point allocation fail"); goto fin; } /* process the request */ if (((data->server_scalar = BN_new()) == NULL) || ((data->k = BN_new()) == NULL) || ((K = EC_POINT_new(data->grp->group)) == NULL) || ((point = EC_POINT_new(data->grp->group)) == NULL) || ((data->server_element = EC_POINT_new(data->grp->group)) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation " "fail"); goto fin; } /* element, x then y, followed by scalar */ ptr = (u8 *) payload; BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), x); ptr += BN_num_bytes(data->grp->prime); BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), y); ptr += BN_num_bytes(data->grp->prime); BN_bin2bn(ptr, BN_num_bytes(data->grp->order), data->server_scalar); if (!EC_POINT_set_affine_coordinates_GFp(data->grp->group, data->server_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element " "fail"); goto fin; } /* check to ensure server's element is not in a small sub-group */ if (BN_cmp(cofactor, BN_value_one())) { if (!EC_POINT_mul(data->grp->group, point, NULL, data->server_element, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " "server element by order!\n"); goto fin; } if (EC_POINT_is_at_infinity(data->grp->group, point)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): server element " "is at infinity!\n"); goto fin; } } /* compute the shared key, k */ if ((!EC_POINT_mul(data->grp->group, K, NULL, data->grp->pwe, data->server_scalar, data->bnctx)) || (!EC_POINT_add(data->grp->group, K, K, data->server_element, data->bnctx)) || (!EC_POINT_mul(data->grp->group, K, NULL, K, data->private_value, data->bnctx))) { wpa_printf(MSG_INFO, "EAP-PWD (peer): computing shared key " "fail"); goto fin; } /* ensure that the shared key isn't in a small sub-group */ if (BN_cmp(cofactor, BN_value_one())) { if (!EC_POINT_mul(data->grp->group, K, NULL, K, cofactor, NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " "shared key point by order"); goto fin; } } /* * This check is strictly speaking just for the case above where * co-factor > 1 but it was suggested that even though this is probably * never going to happen it is a simple and safe check "just to be * sure" so let's be safe. */ if (EC_POINT_is_at_infinity(data->grp->group, K)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): shared key point is at " "infinity!\n"); goto fin; } if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, K, data->k, NULL, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to extract " "shared secret from point"); goto fin; } /* now do the response */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, data->my_element, x, y, data->bnctx)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): point assignment fail"); goto fin; } if (((scalar = os_malloc(BN_num_bytes(data->grp->order))) == NULL) || ((element = os_malloc(BN_num_bytes(data->grp->prime) * 2)) == NULL)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): data allocation fail"); goto fin; } /* * bignums occupy as little memory as possible so one that is * sufficiently smaller than the prime or order might need pre-pending * with zeros. */ os_memset(scalar, 0, BN_num_bytes(data->grp->order)); os_memset(element, 0, BN_num_bytes(data->grp->prime) * 2); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->my_scalar); BN_bn2bin(data->my_scalar, scalar + offset); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, element + offset); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, sizeof(struct eap_pwd_hdr) + BN_num_bytes(data->grp->order) + (2 * BN_num_bytes(data->grp->prime)), EAP_CODE_RESPONSE, eap_get_id(reqData)); if (resp == NULL) goto fin; wpabuf_put_u8(resp, EAP_PWD_OPCODE_COMMIT_EXCH); /* we send the element as (x,y) follwed by the scalar */ wpabuf_put_data(resp, element, (2 * BN_num_bytes(data->grp->prime))); wpabuf_put_data(resp, scalar, BN_num_bytes(data->grp->order)); fin: os_free(scalar); os_free(element); BN_free(x); BN_free(y); BN_free(cofactor); EC_POINT_free(K); EC_POINT_free(point); if (resp == NULL) eap_pwd_state(data, FAILURE); else eap_pwd_state(data, PWD_Confirm_Req); return resp; }
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. * It does not contain branches that may leak sensitive information. */ static BIGNUM * BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; BIGNUM local_A, local_B; BIGNUM *pA, *pB; BIGNUM *ret = NULL; int sign; 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)) { /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pB = &local_B; BN_with_flags(pB, B, BN_FLG_CONSTTIME); if (!BN_nnmod(B, pB, 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|). */ while (!BN_is_zero(B)) { BIGNUM *tmp; /* * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pA = &local_A; BN_with_flags(pA, A, BN_FLG_CONSTTIME); /* (D, M) := (A/B, A%B) ... */ if (!BN_div(D, M, pA, 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. */ 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_NO_BRANCH, 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); }
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; EC_POINT *tmp_point=NULL; const EC_GROUP *group; int ret = 0; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); return 0; } } else ctx = ctx_in; k = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ order = BN_new(); X = BN_new(); if (!k || !r || !order || !X) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } do { /* get random k */ do if (!BN_rand_range(k, order)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } while (BN_is_zero(k)); /* We do not want timing information to leak the length of k, * so we compute G*k using an equivalent scalar of fixed * bit-length. */ if (!BN_add(k, k, order)) goto err; if (BN_num_bits(k) <= BN_num_bits(order)) if (!BN_add(k, k, order)) goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else /* NID_X9_62_characteristic_two_field */ { if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } #endif if (!BN_nnmod(r, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* compute the inverse of k */ if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } /* clear old values if necessary */ BN_clear_free(*rp); BN_clear_free(*kinvp); /* save the pre-computed values */ *rp = r; *kinvp = k; ret = 1; err: if (!ret) { BN_clear_free(k); BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); BN_free(order); EC_POINT_free(tmp_point); BN_clear_free(X); return(ret); }