Пример #1
0
void DH_compute_key(DH_CTX *dh_ctx)
{
    BI_CTX *bi_ctx = bi_initialize();
    int len = dh_ctx->len;
    bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus
    bigint *x = bi_import(bi_ctx, dh_ctx->x, len); //private key
    bigint *gy = bi_import(bi_ctx, dh_ctx->gy, len);  //public key(peer)
    bigint *k;                                      //negotiated(session) key

    bi_permanent(x);
    bi_permanent(gy);

    //calculate session key k = gy^x mod p
    bi_set_mod(bi_ctx, p,  BIGINT_M_OFFSET);
    bi_ctx->mod_offset = BIGINT_M_OFFSET;
    k = bi_mod_power(bi_ctx, gy, x);
    bi_permanent(k);

    bi_export(bi_ctx, k, dh_ctx->k, len);

    bi_depermanent(x);
    bi_depermanent(gy);
    bi_depermanent(k);
    bi_free(bi_ctx, x);
    bi_free(bi_ctx, gy);
    bi_free(bi_ctx, k);

    bi_free_mod(bi_ctx, BIGINT_M_OFFSET);
    bi_terminate(bi_ctx);
}
Пример #2
0
void DH_generate_key(DH_CTX *dh_ctx)
{
    BI_CTX *bi_ctx = bi_initialize();
    int len = dh_ctx->len;
    bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus
    bigint *g = bi_import(bi_ctx, dh_ctx->g, dh_ctx->glen); //generator
    bigint *x, *gx;

    bi_permanent(g);

    //generate private key  X
    get_random_NZ(len, dh_ctx->x);
    x = bi_import(bi_ctx, dh_ctx->x, len);
    bi_permanent(x);

    //calculate public key gx = g^x mod p
    bi_set_mod(bi_ctx, p,  BIGINT_M_OFFSET);
    bi_ctx->mod_offset = BIGINT_M_OFFSET;
    gx = bi_mod_power(bi_ctx, g, x);
    bi_permanent(gx);

    bi_export(bi_ctx, x, dh_ctx->x, len);
    bi_export(bi_ctx, gx, dh_ctx->gx, len);

    bi_depermanent(g);
    bi_depermanent(x);
    bi_depermanent(gx);
    bi_free(bi_ctx, g);
    bi_free(bi_ctx, x);
    bi_free(bi_ctx, gx);

    bi_free_mod(bi_ctx, BIGINT_M_OFFSET);
    bi_terminate(bi_ctx);
}
Пример #3
0
void RSA_priv_key_new(RSA_CTX **ctx, const uint8_t *modulus, int mod_len,
                      const uint8_t *pub_exp, int pub_len,
                      const uint8_t *priv_exp, int priv_len, const uint8_t *p,
                      int p_len, const uint8_t *q, int q_len, const uint8_t *dP,
                      int dP_len, const uint8_t *dQ, int dQ_len,
                      const uint8_t *qInv, int qInv_len) {
  RSA_CTX *rsa_ctx;
  BI_CTX *bi_ctx;
  RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len);
  rsa_ctx = *ctx;
  bi_ctx = rsa_ctx->bi_ctx;
  rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len);
  bi_permanent(rsa_ctx->d);

  rsa_ctx->p = bi_import(bi_ctx, p, p_len);
  rsa_ctx->q = bi_import(bi_ctx, q, q_len);
  rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len);
  rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len);
  rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len);
  bi_permanent(rsa_ctx->dP);
  bi_permanent(rsa_ctx->dQ);
  bi_permanent(rsa_ctx->qInv);
  bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET);
  bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET);
}
Пример #4
0
/**
 * @brief Pre-calculate some of the expensive steps in reduction. 
 *
 * This function should only be called once (normally when a session starts).
 * When the session is over, bi_free_mod() should be called. bi_mod_power()
 * relies on this function being called.
 * @param ctx [in]  The bigint session context.
 * @param bim [in]  The bigint modulus that will be used.
 * @param mod_offset [in] There are three moduluii that can be stored - the
 * standard modulus, and its two primes p and q. This offset refers to which
 * modulus we are referring to.
 * @see bi_free_mod(), bi_mod_power().
 */
void ICACHE_FLASH_ATTR bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
{
    int k = bim->size;
    comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
#ifdef CONFIG_BIGINT_MONTGOMERY
    bigint *R, *R2;
#endif

    ctx->bi_mod[mod_offset] = bim;
    bi_permanent(ctx->bi_mod[mod_offset]);
    ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
    bi_permanent(ctx->bi_normalised_mod[mod_offset]);

#if defined(CONFIG_BIGINT_MONTGOMERY)
    /* set montgomery variables */
    R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1);     /* R */
    R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1);  /* R^2 */
    ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2);             /* R^2 mod m */
    ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R);               /* R mod m */

    bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
    bi_permanent(ctx->bi_R_mod_m[mod_offset]);

    ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);

#elif defined (CONFIG_BIGINT_BARRETT)
    ctx->bi_mu[mod_offset] = 
        bi_divide(ctx, comp_left_shift(
            bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
    bi_permanent(ctx->bi_mu[mod_offset]);
#endif
}
Пример #5
0
/**
 * @brief Start a new bigint context.
 * @return A bigint context.
 */
BI_CTX *ICACHE_FLASH_ATTR bi_initialize(void) {
	/* calloc() sets everything to zero */
	BI_CTX *ctx = (BI_CTX *)os_zalloc(sizeof(BI_CTX));

	/* the radix */
	ctx->bi_radix = alloc(ctx, 2);
	ctx->bi_radix->comps[0] = 0;
	ctx->bi_radix->comps[1] = 1;
	bi_permanent(ctx->bi_radix);
	return ctx;
}
Пример #6
0
/*
 * Work out g1, g3, g5, g7... etc for the sliding-window algorithm
 */
static void ICACHE_FLASH_ATTR precompute_slide_window(BI_CTX *ctx, int window, bigint *g1) {
	int k = 1, i;
	bigint *g2;

	for (i = 0; i < window - 1; i++) { /* compute 2^(window-1) */
		k <<= 1;
	}

	ctx->g = (bigint **)os_malloc(k * sizeof(bigint *));
	ctx->g[0] = bi_clone(ctx, g1);
	bi_permanent(ctx->g[0]);
	g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0]));   /* g^2 */

	for (i = 1; i < k; i++) {
		ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i - 1], bi_copy(g2)));
		bi_permanent(ctx->g[i]);
	}

	bi_free(ctx, g2);
	ctx->window = k;
}
Пример #7
0
void RSA_pub_key_new(RSA_CTX **ctx, 
        const uint8_t *modulus, int mod_len,
        const uint8_t *pub_exp, int pub_len)
{
    RSA_CTX *rsa_ctx;
    BI_CTX *bi_ctx = bi_initialize();
    *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
    rsa_ctx = *ctx;
    rsa_ctx->bi_ctx = bi_ctx;
    rsa_ctx->num_octets = (mod_len & 0xFFF0);
    rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
    bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
    rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
    bi_permanent(rsa_ctx->e);
}
Пример #8
0
void RSA_pub_key_new(RSA_CTX **ctx, const uint8_t *modulus, int mod_len,
                     const uint8_t *pub_exp, int pub_len) {
  RSA_CTX *rsa_ctx;
  BI_CTX *bi_ctx;

  if (*ctx) /* if we load multiple certs, dump the old one */
    RSA_free(*ctx);

  bi_ctx = bi_initialize();
  *ctx = (RSA_CTX *) calloc(1, sizeof(RSA_CTX));
  rsa_ctx = *ctx;
  rsa_ctx->bi_ctx = bi_ctx;
  rsa_ctx->num_octets = mod_len;
  rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
  bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
  rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
  bi_permanent(rsa_ctx->e);
}
Пример #9
0
/**
 * @brief Perform a modular exponentiation.
 *
 * This function requires bi_set_mod() to have been called previously. This is 
 * one of the optimisations used for performance.
 * @param ctx [in]  The bigint session context.
 * @param bi  [in]  The bigint on which to perform the mod power operation.
 * @param biexp [in] The bigint exponent.
 * @return The result of the mod exponentiation operation
 * @see bi_set_mod().
 */
bigint * ICACHE_FLASH_ATTR bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
{
    int i = find_max_exp_index(biexp), j, window_size = 1;
    bigint *biR = int_to_bi(ctx, 1);

#if defined(CONFIG_BIGINT_MONTGOMERY)
    uint8_t mod_offset = ctx->mod_offset;
    if (!ctx->use_classical)
    {
        /* preconvert */
        bi = bi_mont(ctx, 
                bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset]));    /* x' */
        bi_free(ctx, biR);
        biR = ctx->bi_R_mod_m[mod_offset];                              /* A */
    }
#endif

    check(bi);
    check(biexp);

#ifdef CONFIG_BIGINT_SLIDING_WINDOW
    for (j = i; j > 32; j /= 5) /* work out an optimum size */
        window_size++;

    /* work out the slide constants */
    precompute_slide_window(ctx, window_size, bi);
#else   /* just one constant */
    ctx->g = (bigint **)SSL_MALLOC(sizeof(bigint *));
    ctx->g[0] = bi_clone(ctx, bi);
    ctx->window = 1;
    bi_permanent(ctx->g[0]);
#endif

    /* if sliding-window is off, then only one bit will be done at a time and
     * will reduce to standard left-to-right exponentiation */
    do
    {
        if (exp_bit_is_one(biexp, i))
        {
            int l = i-window_size+1;
            int part_exp = 0;

            if (l < 0)  /* LSB of exponent will always be 1 */
                l = 0;
            else
            {
                while (exp_bit_is_one(biexp, l) == 0)
                    l++;    /* go back up */
            }

            /* build up the section of the exponent */
            for (j = i; j >= l; j--)
            {
                biR = bi_residue(ctx, bi_square(ctx, biR));
                if (exp_bit_is_one(biexp, j))
                    part_exp++;

                if (j != l)
                    part_exp <<= 1;
            }

            part_exp = (part_exp-1)/2;  /* adjust for array */
            biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
            i = l-1;
        }
        else    /* square it */
        {
            biR = bi_residue(ctx, bi_square(ctx, biR));
            i--;
        }
    } while (i >= 0);
     
    /* cleanup */
    for (i = 0; i < ctx->window; i++)
    {
        bi_depermanent(ctx->g[i]);
        bi_free(ctx, ctx->g[i]);
    }

    SSL_FREE(ctx->g);
    bi_free(ctx, bi);
    bi_free(ctx, biexp);
#if defined CONFIG_BIGINT_MONTGOMERY
    return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */
#else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */
    return biR;
#endif
}