/* S = (A * v^u) ^ b % N * this is our shared key (server premaster secret) */ mpi_t _gnutls_calc_srp_S1 (mpi_t A, mpi_t b, mpi_t u, mpi_t v, mpi_t n) { mpi_t tmp1 = NULL, tmp2 = NULL; mpi_t S = NULL; S = _gnutls_mpi_alloc_like (n); if (S == NULL) 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 (&tmp1); _gnutls_mpi_release (&tmp2); return S; freeall: _gnutls_mpi_release (&tmp1); _gnutls_mpi_release (&tmp2); return NULL; }
/* A = g^a % N * returns A and a (which is random) */ bigint_t _gnutls_calc_srp_A(bigint_t * a, bigint_t g, bigint_t n) { bigint_t tmpa; bigint_t A; int ret; ret = _gnutls_mpi_init_multi(&A, &tmpa, NULL); if (ret < 0) { gnutls_assert(); return NULL; } _gnutls_mpi_random_modp(tmpa, n, GNUTLS_RND_RANDOM); ret = _gnutls_mpi_powm(A, g, tmpa, n); if (ret < 0) goto error; if (a != NULL) *a = tmpa; else _gnutls_mpi_release(&tmpa); return A; error: _gnutls_mpi_release(&tmpa); _gnutls_mpi_release(&A); return NULL; }
/* A = g^a % N * returns A and a (which is random) */ mpi_t _gnutls_calc_srp_A (mpi_t * a, mpi_t g, mpi_t n) { mpi_t tmpa; mpi_t A; int bits; bits = _gnutls_mpi_get_nbits (n); tmpa = _gnutls_mpi_snew (bits); if (tmpa == NULL) { gnutls_assert (); return NULL; } _gnutls_mpi_randomize (tmpa, bits, GCRY_STRONG_RANDOM); A = _gnutls_mpi_snew (bits); if (A == NULL) { gnutls_assert (); _gnutls_mpi_release (&tmpa); return NULL; } _gnutls_mpi_powm (A, g, tmpa, n); if (a != NULL) *a = tmpa; else _gnutls_mpi_release (&tmpa); return A; }
static int wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo, gnutls_direction_t direction, gnutls_pk_params_st * params) { int result; if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA) { /* do not trust the generated values. Some old private keys * generated by us have mess on the values. Those were very * old but it seemed some of the shipped example private * keys were as old. */ mpz_invert (TOMPZ (params->params[RSA_COEF]), TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1])); /* calculate exp1 [6] and exp2 [7] */ _gnutls_mpi_release (¶ms->params[RSA_E1]); _gnutls_mpi_release (¶ms->params[RSA_E2]); result = calc_rsa_exp (params); if (result < 0) { gnutls_assert (); return result; } params->params_nr = RSA_PRIVATE_PARAMS; } return 0; }
/* A = g^a % N * returns A and a (which is random) */ bigint_t _gnutls_calc_srp_A (bigint_t * a, bigint_t g, bigint_t n) { bigint_t tmpa; bigint_t A; int bits; bits = _gnutls_mpi_get_nbits (n); tmpa = _gnutls_mpi_randomize (NULL, bits, GNUTLS_RND_RANDOM); A = _gnutls_mpi_new (bits); if (A == NULL) { gnutls_assert (); _gnutls_mpi_release (&tmpa); return NULL; } _gnutls_mpi_powm (A, g, tmpa, n); if (a != NULL) *a = tmpa; else _gnutls_mpi_release (&tmpa); return A; }
/* returns the public value (X), and the secret (ret_x). */ mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime) { mpi_t e, x; int x_size = _gnutls_mpi_get_nbits (prime) - 1; /* The size of the secret key is less than * prime/2 */ if (x_size > MAX_BITS || x_size <= 0) { gnutls_assert (); return NULL; } x = _gnutls_mpi_new (x_size); if (x == NULL) { gnutls_assert (); if (ret_x) *ret_x = NULL; return NULL; } /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt * which does not really check the bits given but the bytes. */ do { _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM); /* Check whether x is zero. */ } while (_gnutls_mpi_cmp_ui (x, 0) == 0); e = _gnutls_mpi_alloc_like (prime); if (e == NULL) { gnutls_assert (); if (ret_x) *ret_x = NULL; _gnutls_mpi_release (&x); return NULL; } _gnutls_mpi_powm (e, g, x, prime); if (ret_x) *ret_x = x; else _gnutls_mpi_release (&x); return e; }
/**************** * Choose a random value b and calculate B = (k* v + g^b) % N. * where k == SHA1(N|g) * Return: B and if ret_b is not NULL b. */ bigint_t _gnutls_calc_srp_B(bigint_t * ret_b, bigint_t g, bigint_t n, bigint_t v) { bigint_t tmpB = NULL, tmpV = NULL; bigint_t b = NULL, B = NULL, k = NULL; int ret; /* calculate: B = (k*v + g^b) % N */ ret = _gnutls_mpi_init_multi(&tmpV, &tmpB, &B, &b, NULL); if (ret < 0) return NULL; _gnutls_mpi_random_modp(b, n, GNUTLS_RND_RANDOM); k = _gnutls_calc_srp_u(n, g, n); if (k == NULL) { gnutls_assert(); goto error; } ret = _gnutls_mpi_mulm(tmpV, k, v, n); if (ret < 0) { gnutls_assert(); goto error; } ret = _gnutls_mpi_powm(tmpB, g, b, n); if (ret < 0) { gnutls_assert(); goto error; } ret = _gnutls_mpi_addm(B, tmpV, tmpB, n); if (ret < 0) { gnutls_assert(); goto error; } _gnutls_mpi_release(&k); _gnutls_mpi_release(&tmpB); _gnutls_mpi_release(&tmpV); if (ret_b) *ret_b = b; else _gnutls_mpi_release(&b); return B; error: _gnutls_mpi_release(&b); _gnutls_mpi_release(&B); _gnutls_mpi_release(&k); _gnutls_mpi_release(&tmpB); _gnutls_mpi_release(&tmpV); return NULL; }
/** * gnutls_dh_params_deinit: * @dh_params: The parameters * * This function will deinitialize the DH parameters type. **/ void gnutls_dh_params_deinit(gnutls_dh_params_t dh_params) { if (dh_params == NULL) return; _gnutls_mpi_release(&dh_params->params[0]); _gnutls_mpi_release(&dh_params->params[1]); gnutls_free(dh_params); }
/* returns the blinded c and the inverse of a random * number r; */ static bigint_t rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri) { bigint_t nc = NULL, r = NULL, ri = NULL; /* nc = c*(r^e) * ri = r^(-1) */ nc = _gnutls_mpi_alloc_like (n); if (nc == NULL) { gnutls_assert (); return NULL; } ri = _gnutls_mpi_alloc_like (n); if (nc == NULL) { gnutls_assert (); goto fail; } r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n), GNUTLS_RND_NONCE); if (r == NULL) { gnutls_assert (); goto fail; } /* invert r */ if (mpz_invert (ri, r, n) == 0) { gnutls_assert (); goto fail; } /* r = r^e */ _gnutls_mpi_powm (r, r, e, n); _gnutls_mpi_mulm (nc, c, r, n); *_ri = ri; _gnutls_mpi_release (&r); return nc; fail: _gnutls_mpi_release (&nc); _gnutls_mpi_release (&r); return NULL; }
static int wrap_gcry_pk_fixup (gnutls_pk_algorithm_t algo, gnutls_direction_t direction, gnutls_pk_params_st * params) { int ret, result; /* only for RSA we invert the coefficient --pgp type */ if (algo != GNUTLS_PK_RSA) return 0; if (params->params[5] == NULL) params->params[5] = _gnutls_mpi_new (_gnutls_mpi_get_nbits (params->params[0])); if (params->params[5] == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } ret = 1; if (direction == GNUTLS_IMPORT) { /* calculate exp1 [6] and exp2 [7] */ _gnutls_mpi_release (¶ms->params[6]); _gnutls_mpi_release (¶ms->params[7]); result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS); if (result < 0) { gnutls_assert (); return result; } ret = gcry_mpi_invm (params->params[5], params->params[3], params->params[4]); params->params_nr = RSA_PRIVATE_PARAMS; } else if (direction == GNUTLS_EXPORT) ret = gcry_mpi_invm (params->params[5], params->params[4], params->params[3]); if (ret == 0) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return 0; }
static int calc_ecdh_key( gnutls_session_t session, gnutls_datum_t * psk_key) { gnutls_pk_params_st pub; int ret; memset(&pub,0,sizeof(pub)); pub.params[ECC_PRIME] = session->key.ecdh_params.params[ECC_PRIME]; pub.params[ECC_ORDER] = session->key.ecdh_params.params[ECC_ORDER]; pub.params[ECC_A] = session->key.ecdh_params.params[ECC_A]; pub.params[ECC_B] = session->key.ecdh_params.params[ECC_B]; pub.params[ECC_GX] = session->key.ecdh_params.params[ECC_GX]; pub.params[ECC_GY] = session->key.ecdh_params.params[ECC_GY]; pub.params[ECC_X] = session->key.ecdh_x; pub.params[ECC_Y] = session->key.ecdh_y; if (psk_key == NULL) ret = _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key, &session->key.ecdh_params, &pub); else { gnutls_datum_t tmp_dh_key; ret = _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key, &session->key.ecdh_params, &pub); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key); _gnutls_free_datum (&tmp_dh_key); } if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = 0; cleanup: /* no longer needed */ _gnutls_mpi_release (&session->key.ecdh_x); _gnutls_mpi_release (&session->key.ecdh_y); gnutls_pk_params_release( &session->key.ecdh_params); return ret; }
/* * Copyright (C) 2007-2012 Free Software Foundation, Inc. * * Author: Nikos Mavrogiannopoulos, Simon Josefsson * * This file is part of GnuTLS. * * GnuTLS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * GnuTLS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GnuTLS; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include "utils.h" #include "../lib/gnutls_int.h" #include "../lib/gnutls_mpi.h" #include "../lib/gnutls_errors.h" #include "../lib/debug.h" static void tls_log_func (int level, const char *str) { fprintf (stderr, "|<%d>| %s", level, str); } #define RND_BITS 510 /* not multiple of 8 */ void doit (void) { int rc; bigint_t n1, n2, n3, n4; gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (99); n1 = _gnutls_mpi_new (1000); if (n1 == NULL) fail ("mpi_new failed\n"); n2 = _gnutls_mpi_set_ui (NULL, 2); if (n2 == NULL) fail ("mpi_set_ui failed\n"); n3 = _gnutls_mpi_set_ui (NULL, 5); if (n3 == NULL) fail ("mpi_set_ui failed\n"); _gnutls_mpi_randomize (n1, RND_BITS, GNUTLS_RND_NONCE); _gnutls_mpi_log ("rand:", n1); rc = _gnutls_mpi_get_nbits (n1); if (rc > RND_BITS) fail ("mpi_get_nbits failed... returned %d\n", rc); n4 = _gnutls_mpi_addm (NULL, n1, n3, n2); if (n4 == NULL) fail ("mpi_set_ui failed\n"); if (_gnutls_mpi_cmp_ui (n4, 0) != 0 && _gnutls_mpi_cmp_ui (n4, 1) != 0) fail ("mpi_cmp_ui failed\n"); _gnutls_mpi_release (&n1); _gnutls_mpi_release (&n2); _gnutls_mpi_release (&n3); _gnutls_mpi_release (&n4); gnutls_global_deinit (); if (debug) success ("mpi ops ok\n"); }
/** * gnutls_dh_params_import_dsa: * @dh_params: The parameters * @key: holds a DSA private key * * This function will import the prime and generator of the DSA key for use * in the Diffie-Hellman key exchange. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_dh_params_import_dsa(gnutls_dh_params_t dh_params, gnutls_x509_privkey_t key) { gnutls_datum_t p, g, q; bigint_t tmp_q; int ret; ret = gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, NULL, NULL); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_mpi_init_scan_nz(&tmp_q, q.data, q.size); if (ret < 0) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } ret = gnutls_dh_params_import_raw2(dh_params, &p, &g, _gnutls_mpi_get_nbits(tmp_q)); _gnutls_mpi_release(&tmp_q); cleanup: gnutls_free(p.data); gnutls_free(g.data); gnutls_free(q.data); return ret; }
static int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p, unsigned q_bits) { /* just in case we are resuming a session */ gnutls_pk_params_release(&session->key.proto.tls12.dh.params); gnutls_pk_params_init(&session->key.proto.tls12.dh.params); session->key.proto.tls12.dh.params.params[DH_G] = _gnutls_mpi_copy(g); if (session->key.proto.tls12.dh.params.params[DH_G] == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); session->key.proto.tls12.dh.params.params[DH_P] = _gnutls_mpi_copy(p); if (session->key.proto.tls12.dh.params.params[DH_P] == NULL) { _gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]); return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); } session->key.proto.tls12.dh.params.params_nr = 3; /* include empty q */ session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH; session->key.proto.tls12.dh.params.qbits = q_bits; return 0; }
int _gnutls_x509_privkey_to_gkey (gnutls_privkey * dest, gnutls_x509_privkey_t src) { int i, ret; memset (dest, 0, sizeof (gnutls_privkey)); for (i = 0; i < src->params_size; i++) { dest->params[i] = _gnutls_mpi_copy (src->params[i]); if (dest->params[i] == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } } dest->pk_algorithm = src->pk_algorithm; dest->params_size = src->params_size; return 0; cleanup: for (i = 0; i < src->params_size; i++) { _gnutls_mpi_release (&dest->params[i]); } return ret; }
int _gnutls_pk_params_copy(gnutls_pk_params_st * dst, const gnutls_pk_params_st * src) { unsigned int i, j; dst->params_nr = 0; if (src == NULL || src->params_nr == 0) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } dst->flags = src->flags; dst->algo = src->algo; for (i = 0; i < src->params_nr; i++) { dst->params[i] = _gnutls_mpi_copy(src->params[i]); if (dst->params[i] == NULL) { goto fail; } dst->params_nr++; } return 0; fail: for (j = 0; j < i; j++) _gnutls_mpi_release(&dst->params[j]); return GNUTLS_E_MEMORY_ERROR; }
int _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size) { bigint_t tmp = _gnutls_mpi_alloc_like (params[0]); if (params_size < RSA_PRIVATE_PARAMS - 2) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } if (tmp == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } /* [6] = d % p-1, [7] = d % q-1 */ _gnutls_mpi_sub_ui (tmp, params[3], 1); params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp); _gnutls_mpi_sub_ui (tmp, params[4], 1); params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp); _gnutls_mpi_release (&tmp); if (params[7] == NULL || params[6] == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } return 0; }
/* Checks if a%n==0,+1,-1%n which is a fatal srp error. * Returns a proper error code in that case, and 0 when * all are ok. */ inline static int check_a_mod_n (bigint_t a, bigint_t n) { int ret; bigint_t r; r = _gnutls_mpi_mod (a, n); if (r == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } ret = _gnutls_mpi_cmp_ui (r, 0); _gnutls_mpi_release (&r); if (ret == 0) { gnutls_assert (); return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; } return 0; }
int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src) { int i, j; dst->params_nr = 0; if (src == NULL || src->params_nr == 0) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } for (i = 0; i < src->params_nr; i++) { dst->params[i] = _gnutls_mpi_set (NULL, src->params[i]); if (dst->params[i] == NULL) { for (j = 0; j < i; j++) _gnutls_mpi_release (&dst->params[j]); return GNUTLS_E_MEMORY_ERROR; } dst->params_nr++; } return 0; }
int _gnutls_ecc_ansi_x963_import(const uint8_t * in, unsigned long inlen, bigint_t * x, bigint_t * y) { int ret; /* must be odd */ if ((inlen & 1) == 0) { return GNUTLS_E_INVALID_REQUEST; } /* check for 4 */ if (in[0] != 4) { return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); } /* read data */ ret = _gnutls_mpi_scan(x, in + 1, (inlen - 1) >> 1); if (ret < 0) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ret = _gnutls_mpi_scan(y, in + 1 + ((inlen - 1) >> 1), (inlen - 1) >> 1); if (ret < 0) { _gnutls_mpi_release(x); return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); } return 0; }
/* Checks if b%n==0 which is a fatal srp error. * Returns a proper error code in that case, and 0 when * all are ok. */ inline static int check_b_mod_n (mpi_t b, mpi_t n) { int ret; mpi_t r = _gnutls_mpi_alloc_like (b); if (r == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } _gnutls_mpi_mod (r, b, n); ret = _gnutls_mpi_cmp_ui (r, 0); _gnutls_mpi_release (&r); if (ret == 0) { gnutls_assert (); return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; } return 0; }
int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params, int params_len) { int i, j; dst->params_nr = 0; if (params_len == 0 || params == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } for (i = 0; i < params_len; i++) { dst->params[i] = _gnutls_mpi_set (NULL, params[i]); if (dst->params[i] == NULL) { for (j = 0; j < i; j++) _gnutls_mpi_release (&dst->params[j]); return GNUTLS_E_MEMORY_ERROR; } dst->params_nr++; } return 0; }
/** * gnutls_dh_params_import_raw - import DH parameters * @dh_params: Is a structure that will hold the prime numbers * @prime: holds the new prime * @generator: holds the new generator * * This function will replace the pair of prime and generator for use * in the Diffie-Hellman key exchange. The new parameters should be * stored in the appropriate gnutls_datum. * * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, * otherwise an error code is returned. **/ int gnutls_dh_params_import_raw (gnutls_dh_params_t dh_params, const gnutls_datum_t * prime, const gnutls_datum_t * generator) { bigint_t tmp_prime, tmp_g; size_t siz; siz = prime->size; if (_gnutls_mpi_scan_nz (&tmp_prime, prime->data, siz)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } siz = generator->size; if (_gnutls_mpi_scan_nz (&tmp_g, generator->data, siz)) { _gnutls_mpi_release (&tmp_prime); gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } /* store the generated values */ dh_params->params[0] = tmp_prime; dh_params->params[1] = tmp_g; return 0; }
static int calc_ecdh_key(gnutls_session_t session, gnutls_datum_t * psk_key, gnutls_ecc_curve_t curve) { gnutls_pk_params_st pub; int ret; gnutls_pk_params_init(&pub); pub.params[ECC_X] = session->key.ecdh_x; pub.params[ECC_Y] = session->key.ecdh_y; pub.flags = curve; if (psk_key == NULL) { ret = _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key, &session->key.ecdh_params, &pub); } else { gnutls_datum_t tmp_dh_key; ret = _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key, &session->key.ecdh_params, &pub); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = _gnutls_set_psk_session_key(session, psk_key, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = 0; cleanup: /* no longer needed */ _gnutls_mpi_release(&session->key.ecdh_x); _gnutls_mpi_release(&session->key.ecdh_y); gnutls_pk_params_release(&session->key.ecdh_params); return ret; }
static int _gnutls_srp_gx(uint8_t * text, size_t textsize, uint8_t ** result, bigint_t g, bigint_t prime) { bigint_t x, e = NULL; size_t result_size; int ret; if (_gnutls_mpi_init_scan_nz(&x, text, textsize)) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } ret = _gnutls_mpi_init(&e); if (ret < 0) goto cleanup; /* e = g^x mod prime (n) */ ret = _gnutls_mpi_powm(e, g, x, prime); if (ret < 0) goto cleanup; ret = _gnutls_mpi_print(e, NULL, &result_size); if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { *result = gnutls_malloc(result_size); if ((*result) == NULL) { ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } ret = _gnutls_mpi_print(e, *result, &result_size); if (ret < 0) goto cleanup; ret = result_size; } else { gnutls_assert(); ret = GNUTLS_E_MPI_PRINT_FAILED; } cleanup: _gnutls_mpi_release(&e); _gnutls_mpi_release(&x); return ret; }
int _gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result, bigint_t g, bigint_t prime, gnutls_alloc_function galloc_func) { bigint_t x, e; size_t result_size; int ret; if (_gnutls_mpi_scan_nz (&x, text, textsize)) { gnutls_assert (); 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; } /* e = g^x mod prime (n) */ _gnutls_mpi_powm (e, g, x, prime); _gnutls_mpi_release (&x); ret = _gnutls_mpi_print (e, NULL, &result_size); if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { *result = galloc_func (result_size); if ((*result) == NULL) return GNUTLS_E_MEMORY_ERROR; _gnutls_mpi_print (e, *result, &result_size); ret = result_size; } else { gnutls_assert (); ret = GNUTLS_E_MPI_PRINT_FAILED; } _gnutls_mpi_release (&e); return ret; }
/** * gnutls_openpgp_privkey_sign_hash: * @key: Holds the key * @hash: holds the data to be signed * @signature: will contain newly allocated signature * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. * * Deprecated: Use gnutls_privkey_sign_hash() instead. */ int gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, const gnutls_datum_t * hash, gnutls_datum_t * signature) { int result, i; bigint_t params[MAX_PRIV_PARAMS_SIZE]; int params_size = MAX_PRIV_PARAMS_SIZE; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (result == 0) { uint32_t kid[2]; int idx; KEYID_IMPORT (kid, keyid); idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, kid, params, ¶ms_size); } else { pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, NULL, params, ¶ms_size); } if (result < 0) { gnutls_assert (); return result; } result = _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature); for (i = 0; i < params_size; i++) _gnutls_mpi_release (¶ms[i]); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* Do DSA signature calculation. params is p, q, g, y, x in that order. */ int _gnutls_dsa_sign (gnutls_datum_t * signature, const gnutls_datum_t * hash, mpi_t * params, unsigned params_len) { mpi_t rs[2], mdata; int ret; size_t k; k = hash->size; if (k != 20) { /* SHA only */ gnutls_assert (); return GNUTLS_E_PK_SIGN_FAILED; } if (_gnutls_mpi_scan_nz (&mdata, hash->data, &k) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } ret = _gnutls_pk_sign (GCRY_PK_DSA, rs, mdata, params, params_len); /* rs[0], rs[1] now hold r,s */ _gnutls_mpi_release (&mdata); if (ret < 0) { gnutls_assert (); return ret; } ret = encode_ber_rs (signature, rs[0], rs[1]); /* free r,s */ _gnutls_mpi_release (&rs[0]); _gnutls_mpi_release (&rs[1]); if (ret != 0) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } return 0; }
void gnutls_pk_params_release(gnutls_pk_params_st * p) { unsigned int i; for (i = 0; i < p->params_nr; i++) { _gnutls_mpi_release(&p->params[i]); } p->params_nr = 0; }
/* Release an array of MPI values. */ void _cdk_free_mpibuf (size_t n, bigint_t * array) { while (n--) { _gnutls_mpi_release (&array[n]); } }