return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
}
- two = _gnutls_mpi_new(4);
- if (two == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- q = _gnutls_mpi_alloc_like(n);
- if (q == NULL) {
+ ret = _gnutls_mpi_init_multi(&two, &q, &w, NULL);
+ if (ret < 0) {
gnutls_assert();
- ret = GNUTLS_E_MEMORY_ERROR;
- goto error;
+ return ret;
}
/* q = n-1
goto error;
}
- w = _gnutls_mpi_alloc_like(q);
- if (w == NULL) {
- gnutls_assert();
- ret = GNUTLS_E_MEMORY_ERROR;
- goto error;
- }
-
/* check if g^q mod N == N-1
* w = g^q mod N
*/
/* Multi precision integer arithmetic */
typedef struct gnutls_crypto_bigint {
- bigint_t(*bigint_new) (int nbits);
+ int (*bigint_init) (bigint_t*);
+ int (*bigint_init_multi) (bigint_t*, ...);
void (*bigint_release) (bigint_t n);
void (*bigint_clear) (bigint_t n); /* zeros the int */
/* 0 for equality, > 0 for m1>m2, < 0 for m1<m2 */
bigint_t _gnutls_mpi_random_modp(bigint_t, bigint_t p,
gnutls_rnd_level_t level);
-#define _gnutls_mpi_new _gnutls_mpi_ops.bigint_new
+#define _gnutls_mpi_init _gnutls_mpi_ops.bigint_init
+#define _gnutls_mpi_init_multi _gnutls_mpi_ops.bigint_init_multi
#define _gnutls_mpi_clear _gnutls_mpi_ops.bigint_clear
#define _gnutls_mpi_cmp _gnutls_mpi_ops.bigint_cmp
#define _gnutls_mpi_cmp_ui _gnutls_mpi_ops.bigint_cmp_ui
#define _gnutls_mpi_set _gnutls_mpi_ops.bigint_set
#define _gnutls_mpi_set_ui _gnutls_mpi_ops.bigint_set_ui
#define _gnutls_mpi_get_nbits _gnutls_mpi_ops.bigint_get_nbits
-#define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x))
#define _gnutls_mpi_powm _gnutls_mpi_ops.bigint_powm
#define _gnutls_mpi_addm _gnutls_mpi_ops.bigint_addm
#define _gnutls_mpi_subm _gnutls_mpi_ops.bigint_subm
return GNUTLS_E_MPI_SCAN_FAILED;
}
- e = _gnutls_mpi_alloc_like(prime);
- if (e == NULL) {
- gnutls_assert();
- _gnutls_mpi_release(&x);
- return GNUTLS_E_MEMORY_ERROR;
- }
+ ret = _gnutls_mpi_init(&e);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
/* e = g^x mod prime (n) */
_gnutls_mpi_powm(e, g, x, prime);
{
bigint_t tmpB = NULL, tmpV = NULL;
bigint_t b = NULL, B = NULL, k = NULL;
- int bits;
-
+ int ret;
/* calculate: B = (k*v + g^b) % N
*/
- bits = _gnutls_mpi_get_nbits(n);
-
- tmpV = _gnutls_mpi_alloc_like(n);
-
- if (tmpV == NULL) {
- gnutls_assert();
- goto error;
- }
-
- b = _gnutls_mpi_random_modp(NULL, n, GNUTLS_RND_RANDOM);
-
- tmpB = _gnutls_mpi_new(bits);
- if (tmpB == NULL) {
- gnutls_assert();
- goto error;
- }
+ ret = _gnutls_mpi_init_multi(&tmpV, &tmpB, &B, &b, NULL);
+ if (ret < 0)
+ return NULL;
- B = _gnutls_mpi_new(bits);
- if (B == NULL) {
- gnutls_assert();
- goto error;
- }
+ _gnutls_mpi_random_modp(b, n, GNUTLS_RND_RANDOM);
k = _gnutls_calc_srp_u(n, g, n);
if (k == NULL) {
{
bigint_t tmp1 = NULL, tmp2 = NULL;
bigint_t S = NULL;
+ int ret;
- S = _gnutls_mpi_alloc_like(n);
- if (S == NULL)
+ ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, NULL);
+ if (ret < 0)
return NULL;
- tmp1 = _gnutls_mpi_alloc_like(n);
- tmp2 = _gnutls_mpi_alloc_like(n);
-
- if (tmp1 == NULL || tmp2 == NULL)
- goto freeall;
-
_gnutls_mpi_powm(tmp1, v, u, n);
_gnutls_mpi_mulm(tmp2, A, tmp1, n);
_gnutls_mpi_powm(S, tmp2, b, n);
_gnutls_mpi_release(&tmp2);
return S;
-
- freeall:
- _gnutls_mpi_release(&tmp1);
- _gnutls_mpi_release(&tmp2);
- return NULL;
}
/* A = g^a % N
{
bigint_t tmpa;
bigint_t A;
- int bits;
-
- bits = _gnutls_mpi_get_nbits(n);
- tmpa = _gnutls_mpi_random_modp(NULL, n, GNUTLS_RND_RANDOM);
+ int ret;
- A = _gnutls_mpi_new(bits);
- if (A == NULL) {
+ ret = _gnutls_mpi_init_multi(&A, &tmpa, NULL);
+ if (ret < 0) {
gnutls_assert();
- _gnutls_mpi_release(&tmpa);
return NULL;
}
+
+ _gnutls_mpi_random_modp(tmpa, n, GNUTLS_RND_RANDOM);
+
_gnutls_mpi_powm(A, g, tmpa, n);
if (a != NULL)
{
bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL;
bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL;
+ int ret;
- S = _gnutls_mpi_alloc_like(n);
- if (S == NULL)
+ ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, &tmp3, &tmp4, NULL);
+ if (ret < 0)
return NULL;
- tmp1 = _gnutls_mpi_alloc_like(n);
- tmp2 = _gnutls_mpi_alloc_like(n);
- tmp3 = _gnutls_mpi_alloc_like(n);
- if (tmp1 == NULL || tmp2 == NULL || tmp3 == NULL) {
- goto freeall;
- }
-
k = _gnutls_calc_srp_u(n, g, n);
if (k == NULL) {
gnutls_assert();
_gnutls_mpi_mulm(tmp3, tmp1, k, n); /* k*g^x mod n */
_gnutls_mpi_subm(tmp2, B, tmp3, n);
- tmp4 = _gnutls_mpi_alloc_like(n);
- if (tmp4 == NULL)
- goto freeall;
-
_gnutls_mpi_mul(tmp1, u, x);
_gnutls_mpi_add(tmp4, a, tmp1);
_gnutls_mpi_powm(S, tmp2, tmp4, n);
return 0;
}
-static bigint_t wrap_nettle_mpi_new(int nbits)
+static int wrap_nettle_mpi_init(bigint_t *w)
{
- mpz_t *p;
+mpz_t *r;
- p = gnutls_malloc(sizeof(*p));
- if (p == NULL) {
+ r = gnutls_malloc(sizeof(*r));
+ if (r == NULL) {
gnutls_assert();
- return NULL;
+ return GNUTLS_E_MEMORY_ERROR;
}
- if (nbits == 0)
- mpz_init(*p);
- else
- mpz_init2(*p, nbits);
- return p;
+ mpz_init(*r);
+
+ *w = r;
+
+ return 0;
+}
+
+static int wrap_nettle_mpi_init_multi(bigint_t *w, ...)
+{
+ va_list args;
+ bigint_t *next;
+ mpz_t *r;
+ bigint_t* last_failed = NULL;
+
+ r = gnutls_malloc(sizeof(*r));
+ if (r == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ mpz_init(*r);
+ *w = r;
+
+ va_start(args, w);
+
+ do {
+ next = va_arg(args, bigint_t*);
+ if (next != NULL) {
+ r = gnutls_malloc(sizeof(*r));
+ if (r == NULL) {
+ gnutls_assert();
+ va_end(args);
+ last_failed = next;
+ goto fail;
+ }
+ mpz_init(*r);
+ *next = r;
+ }
+ } while(next != 0);
+
+ va_end(args);
+
+ return 0;
+fail:
+ mpz_clear(TOMPZ(*w));
+ gnutls_free(*w);
+ va_start(args, w);
+
+ do {
+ next = va_arg(args, bigint_t*);
+ if (next != last_failed) {
+ mpz_clear(TOMPZ(*next));
+ gnutls_free(*next);
+ }
+ } while(next != last_failed);
+
+ va_end(args);
+
+ return GNUTLS_E_MEMORY_ERROR;
}
static bigint_t
wrap_nettle_mpi_scan(const void *buffer, size_t nbytes,
gnutls_bigint_format_t format)
{
- bigint_t r = wrap_nettle_mpi_new(nbytes * 8);
-
- if (r == NULL) {
+ int ret;
+ bigint_t r;
+
+ ret = wrap_nettle_mpi_init(&r);
+ if (ret < 0) {
gnutls_assert();
- return r;
+ return NULL;
}
if (format == GNUTLS_MPI_FORMAT_USG) {
static bigint_t wrap_nettle_mpi_set(bigint_t w, const bigint_t u)
{
mpz_t *i1, *i2 = u;
+ int ret;
+
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
- if (w == NULL)
- w = _gnutls_mpi_alloc_like(u);
i1 = w;
mpz_set(*i1, *i2);
static bigint_t wrap_nettle_mpi_set_ui(bigint_t w, unsigned long u)
{
mpz_t *i1;
+ int ret;
- if (w == NULL)
- w = wrap_nettle_mpi_new(32);
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
i1 = w;
static bigint_t wrap_nettle_mpi_modm(bigint_t r, const bigint_t a, const bigint_t b)
{
+int ret;
+
if (r == NULL) {
- r = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(b));
- if (r == NULL) return NULL;
+ ret = wrap_nettle_mpi_init(&r);
+ if (ret < 0)
+ return NULL;
}
-
+
mpz_mod(TOMPZ(r), TOMPZ(a), TOMPZ(b));
return r;
wrap_nettle_mpi_powm(bigint_t w, const bigint_t b, const bigint_t e,
const bigint_t m)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(m));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_powm(TOMPZ(w), TOMPZ(b), TOMPZ(e), TOMPZ(m));
wrap_nettle_mpi_addm(bigint_t w, const bigint_t a, const bigint_t b,
const bigint_t m)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_add(TOMPZ(w), TOMPZ(b), TOMPZ(a));
mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
wrap_nettle_mpi_subm(bigint_t w, const bigint_t a, const bigint_t b,
const bigint_t m)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_sub(TOMPZ(w), TOMPZ(a), TOMPZ(b));
mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
wrap_nettle_mpi_mulm(bigint_t w, const bigint_t a, const bigint_t b,
const bigint_t m)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(m));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_mul(TOMPZ(w), TOMPZ(a), TOMPZ(b));
mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
static bigint_t
wrap_nettle_mpi_add(bigint_t w, const bigint_t a, const bigint_t b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(b));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_add(TOMPZ(w), TOMPZ(a), TOMPZ(b));
static bigint_t
wrap_nettle_mpi_sub(bigint_t w, const bigint_t a, const bigint_t b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_sub(TOMPZ(w), TOMPZ(a), TOMPZ(b));
static bigint_t
wrap_nettle_mpi_mul(bigint_t w, const bigint_t a, const bigint_t b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_mul(TOMPZ(w), TOMPZ(a), TOMPZ(b));
static bigint_t
wrap_nettle_mpi_div(bigint_t q, const bigint_t a, const bigint_t b)
{
- if (q == NULL)
- q = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (q == NULL)
- return NULL;
+ if (q == NULL) {
+ ret = wrap_nettle_mpi_init(&q);
+ if (ret < 0)
+ return NULL;
+ }
mpz_cdiv_q(TOMPZ(q), TOMPZ(a), TOMPZ(b));
static bigint_t
wrap_nettle_mpi_add_ui(bigint_t w, const bigint_t a, unsigned long b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_add_ui(TOMPZ(w), TOMPZ(a), b);
static bigint_t
wrap_nettle_mpi_sub_ui(bigint_t w, const bigint_t a, unsigned long b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_sub_ui(TOMPZ(w), TOMPZ(a), b);
static bigint_t
wrap_nettle_mpi_mul_ui(bigint_t w, const bigint_t a, unsigned long b)
{
- if (w == NULL)
- w = wrap_nettle_mpi_new(wrap_nettle_mpi_get_nbits(a));
+int ret;
- if (w == NULL)
- return NULL;
+ if (w == NULL) {
+ ret = wrap_nettle_mpi_init(&w);
+ if (ret < 0)
+ return NULL;
+ }
mpz_mul_ui(TOMPZ(w), TOMPZ(a), b);
static int wrap_nettle_prime_check(bigint_t pp)
{
int ret;
- ret = mpz_probab_prime_p(TOMPZ(pp), PRIME_CHECK_PARAM);
+ ret = mpz_probab_prime_p(TOMPZ(pp), PRIME_CHECK_PARAM);
if (ret > 0) {
return 0;
}
int crypto_bigint_prio = INT_MAX;
gnutls_crypto_bigint_st _gnutls_mpi_ops = {
- .bigint_new = wrap_nettle_mpi_new,
+ .bigint_init = wrap_nettle_mpi_init,
+ .bigint_init_multi = wrap_nettle_mpi_init_multi,
.bigint_cmp = wrap_nettle_mpi_cmp,
.bigint_cmp_ui = wrap_nettle_mpi_cmp_ui,
.bigint_modm = wrap_nettle_mpi_modm,
goto dh_cleanup;
}
- k = _gnutls_mpi_alloc_like(prime);
- if (k == NULL) {
+ ret = _gnutls_mpi_init(&k);
+ if (ret < 0) {
gnutls_assert();
- ret = GNUTLS_E_MEMORY_ERROR;
goto dh_cleanup;
}
#endif
params->params_nr = 0;
- for (i = 0; i < DSA_PRIVATE_PARAMS-2; i++) {
- params->params[i] =
- _gnutls_mpi_alloc_like(&pub.p);
- if (params->params[i] == NULL) {
- ret = GNUTLS_E_MEMORY_ERROR;
- goto dsa_fail;
- }
- params->params_nr++;
+
+ ret = _gnutls_mpi_init_multi(¶ms->params[0], ¶ms->params[1],
+ ¶ms->params[2], NULL);
+ if (ret < 0) {
+ gnutls_assert();
+ goto dsa_fail;
}
+ params->params_nr = 3;
ret = 0;
_gnutls_mpi_set(params->params[0], pub.p);
goto dsa_fail;
}
- params->params[DSA_Y] = _gnutls_mpi_alloc_like(&pub.p);
- if (params->params[DSA_Y] == NULL) {
- ret = GNUTLS_E_MEMORY_ERROR;
- goto dsa_fail;
- }
-
- params->params[DSA_X] = _gnutls_mpi_alloc_like(&pub.p);
- if (params->params[DSA_X] == NULL) {
- _gnutls_mpi_release(¶ms->params[DSA_Y]);
- ret = GNUTLS_E_MEMORY_ERROR;
+ ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL);
+ if (ret < 0) {
+ gnutls_assert();
goto dsa_fail;
}
}
} while(mpz_cmp_ui(y, 1) == 0);
- params->params[DSA_Y] = _gnutls_mpi_alloc_like(&pub.p);
- if (params->params[DSA_Y] == NULL) {
- ret = GNUTLS_E_MEMORY_ERROR;
- goto dh_fail;
- }
-
- params->params[DSA_X] = _gnutls_mpi_alloc_like(&pub.p);
- if (params->params[DSA_X] == NULL) {
- _gnutls_mpi_release(¶ms->params[DSA_Y]);
- ret = GNUTLS_E_MEMORY_ERROR;
+ ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL);
+ if (ret < 0) {
+ gnutls_assert();
goto dh_fail;
}
params->params_nr = 0;
for (i = 0; i < RSA_PRIVATE_PARAMS; i++) {
- params->params[i] =
- _gnutls_mpi_alloc_like(&pub.n);
- if (params->params[i] == NULL) {
- ret = GNUTLS_E_MEMORY_ERROR;
+ ret = _gnutls_mpi_init(¶ms->params[i]);
+ if (ret < 0) {
+ gnutls_assert();
goto rsa_fail;
}
params->params_nr++;
-
}
ret = 0;
ecdsa_generate_keypair(&pub, &key, NULL, rnd_func);
- params->params[ECC_X] = _gnutls_mpi_new(0);
- params->params[ECC_Y] = _gnutls_mpi_new(0);
- params->params[ECC_K] = _gnutls_mpi_new(0);
-
- if (params->params[ECC_X] == NULL
- || params->params[ECC_Y] == NULL
- || params->params[ECC_K] == NULL) {
- _gnutls_mpi_release(¶ms->
- params[ECC_X]);
- _gnutls_mpi_release(¶ms->
- params[ECC_Y]);
- _gnutls_mpi_release(¶ms->
- params[ECC_K]);
- ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ ret = _gnutls_mpi_init_multi(¶ms->params[ECC_X], ¶ms->params[ECC_Y],
+ ¶ms->params[ECC_K], NULL);
+ if (ret < 0) {
+ gnutls_assert();
goto ecc_fail;
}
gnutls_assert_val
(GNUTLS_E_INVALID_REQUEST);
- t1 = _gnutls_mpi_new(256);
- if (t1 == NULL)
+ ret = _gnutls_mpi_init(&t1);
+ if (ret < 0)
return
- gnutls_assert_val
- (GNUTLS_E_MEMORY_ERROR);
+ gnutls_assert_val(ret);
_gnutls_mpi_mulm(t1, params->params[RSA_PRIME1],
params->params[RSA_PRIME2],
gnutls_assert_val
(GNUTLS_E_INVALID_REQUEST);
- t1 = _gnutls_mpi_new(256);
- if (t1 == NULL)
+ ret = _gnutls_mpi_init(&t1);
+ if (ret < 0)
return
- gnutls_assert_val
- (GNUTLS_E_MEMORY_ERROR);
+ gnutls_assert_val(ret);
_gnutls_mpi_powm(t1, params->params[DSA_G],
params->params[DSA_X],
static int calc_rsa_exp(gnutls_pk_params_st * params)
{
- bigint_t tmp = _gnutls_mpi_alloc_like(params->params[0]);
-
+ bigint_t tmp;
+ int ret;
+
if (params->params_nr < RSA_PRIVATE_PARAMS - 2) {
gnutls_assert();
return GNUTLS_E_INTERNAL_ERROR;
}
- if (tmp == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ ret = _gnutls_mpi_init(&tmp);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
/* [6] = d % p-1, [7] = d % q-1 */
_gnutls_mpi_sub_ui(tmp, params->params[3], 1);
}
/* the public key can be generated as g^x mod p */
- pkey->params.params[3] =
- _gnutls_mpi_alloc_like(pkey->params.params[0]);
- if (pkey->params.params[3] == NULL) {
+ ret = _gnutls_mpi_init(&pkey->params.params[3]);
+ if (ret < 0) {
gnutls_assert();
goto error;
}