LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/nettle - mpi.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 107 148 72.3 %
Date: 2020-10-30 04:50:48 Functions: 21 25 84.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GNUTLS.
       7             :  *
       8             :  * The GNUTLS library is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : /* Here lie everything that has to do with large numbers, gmp.
      24             :  */
      25             : 
      26             : #include "gnutls_int.h"
      27             : #include "errors.h"
      28             : #include <algorithms.h>
      29             : #include <num.h>
      30             : #include <mpi.h>
      31             : #include <nettle/bignum.h> /* includes gmp.h */
      32             : #if ENABLE_GOST
      33             : #include "gost/bignum-le.h"
      34             : #endif
      35             : #include <gnettle.h>
      36             : #include <random.h>
      37             : 
      38             : static int
      39      133442 : wrap_nettle_mpi_print(const bigint_t a, void *buffer, size_t * nbytes,
      40             :                       gnutls_bigint_format_t format)
      41             : {
      42      133442 :         unsigned int size;
      43      133442 :         mpz_t *p = (void *) a;
      44             : 
      45      133442 :         if (format == GNUTLS_MPI_FORMAT_USG) {
      46       71128 :                 size = nettle_mpz_sizeinbase_256_u(*p);
      47       62314 :         } else if (format == GNUTLS_MPI_FORMAT_STD) {
      48       60752 :                 size = nettle_mpz_sizeinbase_256_s(*p);
      49             : #if ENABLE_GOST
      50        1562 :         } else if (format == GNUTLS_MPI_FORMAT_ULE) {
      51        1562 :                 size = nettle_mpz_sizeinbase_256_u_le(*p);
      52             : #endif
      53             :         } else {
      54           0 :                 gnutls_assert();
      55           0 :                 return GNUTLS_E_INVALID_REQUEST;
      56             :         }
      57             : 
      58      133442 :         if (buffer == NULL || size > *nbytes) {
      59       59479 :                 *nbytes = size;
      60       59479 :                 gnutls_assert();
      61       59479 :                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
      62             :         }
      63             : 
      64             : #if ENABLE_GOST
      65       73963 :         if (format == GNUTLS_MPI_FORMAT_ULE)
      66         941 :                 nettle_mpz_get_str_256_u_le(size, buffer, *p);
      67             :         else
      68             : #endif
      69       73022 :                 nettle_mpz_get_str_256(size, buffer, *p);
      70       73963 :         *nbytes = size;
      71             : 
      72       73963 :         return 0;
      73             : }
      74             : 
      75      263382 : static int wrap_nettle_mpi_init(bigint_t *w)
      76             : {
      77      263382 : bigint_t r;
      78             : 
      79      263382 :         r = gnutls_malloc(SIZEOF_MPZT);
      80      263382 :         if (r == NULL) {
      81           0 :                 gnutls_assert();
      82           0 :                 return GNUTLS_E_MEMORY_ERROR;
      83             :         }
      84             : 
      85      263382 :         mpz_init(TOMPZ(r));
      86      263382 :         *w = r;
      87             : 
      88      263382 :         return 0;
      89             : }
      90             : 
      91       21381 : static int wrap_nettle_mpi_init_multi(bigint_t *w, ...)
      92             : {
      93       21381 :         va_list args;
      94       21381 :         bigint_t *next;
      95       21381 :         int ret;
      96       21381 :         bigint_t* last_failed = NULL;
      97             : 
      98       21381 :         ret = wrap_nettle_mpi_init(w);
      99       21381 :         if (ret < 0) {
     100           0 :                 gnutls_assert();
     101           0 :                 return ret;
     102             :         }
     103             : 
     104       21381 :         va_start(args, w);
     105             :         
     106       59897 :         do {
     107       59897 :                 next = va_arg(args, bigint_t*);
     108       59897 :                 if (next != NULL) {
     109       38516 :                         ret = wrap_nettle_mpi_init(next);
     110       38516 :                         if (ret < 0) {
     111           0 :                                 gnutls_assert();
     112           0 :                                 va_end(args);
     113           0 :                                 last_failed = next;
     114           0 :                                 goto fail;
     115             :                         }
     116             :                 }
     117       59897 :         } while(next != 0);
     118             :         
     119       21381 :         va_end(args);
     120             : 
     121       21381 :         return 0;
     122           0 : fail:
     123           0 :         mpz_clear(TOMPZ(*w));
     124           0 :         gnutls_free(*w);
     125             : 
     126           0 :         va_start(args, w);
     127             :         
     128           0 :         do {
     129           0 :                 next = va_arg(args, bigint_t*);
     130           0 :                 if (next != last_failed) {
     131           0 :                         mpz_clear(TOMPZ(*next));
     132           0 :                         gnutls_free(*next);
     133             :                 }
     134           0 :         } while(next != last_failed);
     135             :         
     136           0 :         va_end(args);
     137             :         
     138           0 :         return GNUTLS_E_MEMORY_ERROR;
     139             : }
     140             : 
     141             : static int
     142      182881 : wrap_nettle_mpi_scan(bigint_t r, const void *buffer, size_t nbytes,
     143             :                      gnutls_bigint_format_t format)
     144             : {
     145      182881 :         if (format == GNUTLS_MPI_FORMAT_USG) {
     146      181805 :                 nettle_mpz_set_str_256_u(TOMPZ(r), nbytes, buffer);
     147        1076 :         } else if (format == GNUTLS_MPI_FORMAT_STD) {
     148           0 :                 nettle_mpz_set_str_256_s(TOMPZ(r), nbytes, buffer);
     149             : #if ENABLE_GOST
     150        1076 :         } else if (format == GNUTLS_MPI_FORMAT_ULE) {
     151        1076 :                 nettle_mpz_set_str_256_u_le(TOMPZ(r), nbytes, buffer);
     152             : #endif
     153             :         } else {
     154           0 :                 gnutls_assert();
     155           0 :                 goto fail;
     156             :         }
     157             : 
     158             :         return 0;
     159           0 :  fail:
     160           0 :         return GNUTLS_E_MPI_SCAN_FAILED;
     161             : }
     162             : 
     163        9050 : static int wrap_nettle_mpi_cmp(const bigint_t u, const bigint_t v)
     164             : {
     165        9050 :         mpz_t *i1 = u, *i2 = v;
     166             : 
     167        9050 :         return mpz_cmp(*i1, *i2);
     168             : }
     169             : 
     170       53560 : static int wrap_nettle_mpi_cmp_ui(const bigint_t u, unsigned long v)
     171             : {
     172       53560 :         mpz_t *i1 = u;
     173             : 
     174       53560 :         return mpz_cmp_ui(*i1, v);
     175             : }
     176             : 
     177         288 : static int wrap_nettle_mpi_set(bigint_t w, const bigint_t u)
     178             : {
     179         288 :         mpz_set(TOMPZ(w), TOMPZ(u));
     180             : 
     181         288 :         return 0;
     182             : }
     183             : 
     184       17547 : static bigint_t wrap_nettle_mpi_copy(const bigint_t u)
     185             : {
     186       17547 :         int ret;
     187       17547 :         bigint_t w;
     188             : 
     189       17547 :         ret = wrap_nettle_mpi_init(&w);
     190       17547 :         if (ret < 0)
     191             :                 return NULL;
     192             : 
     193       17547 :         mpz_set(TOMPZ(w), u);
     194             : 
     195       17547 :         return w;
     196             : }
     197             : 
     198          95 : static int wrap_nettle_mpi_set_ui(bigint_t w, unsigned long u)
     199             : {
     200          95 :         mpz_set_ui(TOMPZ(w), u);
     201             : 
     202          95 :         return 0;
     203             : }
     204             : 
     205       54673 : static unsigned int wrap_nettle_mpi_get_nbits(bigint_t a)
     206             : {
     207       54673 :         return mpz_sizeinbase(TOMPZ(a), 2);
     208             : }
     209             : 
     210      258583 : static void wrap_nettle_mpi_release(bigint_t a)
     211             : {
     212      258583 :         mpz_clear(TOMPZ(a));
     213      258583 :         gnutls_free(a);
     214      258583 : }
     215             : 
     216       86519 : static void wrap_nettle_mpi_clear(bigint_t a)
     217             : {
     218       86519 :         zeroize_key(TOMPZ(a)[0]._mp_d,
     219             :                TOMPZ(a)[0]._mp_alloc * sizeof(mp_limb_t));
     220       86519 : }
     221             : 
     222       11336 : static int wrap_nettle_mpi_modm(bigint_t r, const bigint_t a, const bigint_t b)
     223             : {
     224       11336 :         if (mpz_cmp_ui(TOMPZ(b), 0) == 0)
     225           5 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     226             : 
     227       11331 :         mpz_mod(TOMPZ(r), TOMPZ(a), TOMPZ(b));
     228             :         
     229       11331 :         return 0;
     230             : }
     231             : 
     232             : static int
     233        7152 : wrap_nettle_mpi_powm(bigint_t w, const bigint_t b, const bigint_t e,
     234             :                      const bigint_t m)
     235             : {
     236        7152 :         mpz_powm(TOMPZ(w), TOMPZ(b), TOMPZ(e), TOMPZ(m));
     237             : 
     238        7152 :         return 0;
     239             : }
     240             : 
     241             : static int
     242         313 : wrap_nettle_mpi_addm(bigint_t w, const bigint_t a, const bigint_t b,
     243             :                      const bigint_t m)
     244             : {
     245         313 :         mpz_add(TOMPZ(w), TOMPZ(b), TOMPZ(a));
     246         313 :         mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
     247             : 
     248         313 :         return 0;
     249             : }
     250             : 
     251             : static int
     252         113 : wrap_nettle_mpi_subm(bigint_t w, const bigint_t a, const bigint_t b,
     253             :                      const bigint_t m)
     254             : {
     255         113 :         mpz_sub(TOMPZ(w), TOMPZ(a), TOMPZ(b));
     256         113 :         mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
     257             : 
     258         113 :         return 0;
     259             : }
     260             : 
     261             : static int
     262         711 : wrap_nettle_mpi_mulm(bigint_t w, const bigint_t a, const bigint_t b,
     263             :                      const bigint_t m)
     264             : {
     265         711 :         mpz_mul(TOMPZ(w), TOMPZ(a), TOMPZ(b));
     266         711 :         mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));
     267             : 
     268         711 :         return 0;
     269             : }
     270             : 
     271             : static int
     272         113 : wrap_nettle_mpi_add(bigint_t w, const bigint_t a, const bigint_t b)
     273             : {
     274         113 :         mpz_add(TOMPZ(w), TOMPZ(a), TOMPZ(b));
     275             : 
     276         113 :         return 0;
     277             : }
     278             : 
     279             : static int
     280           0 : wrap_nettle_mpi_sub(bigint_t w, const bigint_t a, const bigint_t b)
     281             : {
     282           0 :         mpz_sub(TOMPZ(w), TOMPZ(a), TOMPZ(b));
     283             : 
     284           0 :         return 0;
     285             : }
     286             : 
     287             : static int
     288         113 : wrap_nettle_mpi_mul(bigint_t w, const bigint_t a, const bigint_t b)
     289             : {
     290         113 :         mpz_mul(TOMPZ(w), TOMPZ(a), TOMPZ(b));
     291             : 
     292         113 :         return 0;
     293             : }
     294             : 
     295             : /* q = a / b */
     296             : static int
     297           0 : wrap_nettle_mpi_div(bigint_t q, const bigint_t a, const bigint_t b)
     298             : {
     299           0 :         mpz_cdiv_q(TOMPZ(q), TOMPZ(a), TOMPZ(b));
     300             : 
     301           0 :         return 0;
     302             : }
     303             : 
     304             : static int
     305         134 : wrap_nettle_mpi_add_ui(bigint_t w, const bigint_t a, unsigned long b)
     306             : {
     307         134 :         mpz_add_ui(TOMPZ(w), TOMPZ(a), b);
     308             : 
     309         134 :         return 0;
     310             : }
     311             : 
     312             : static int
     313       14808 : wrap_nettle_mpi_sub_ui(bigint_t w, const bigint_t a, unsigned long b)
     314             : {
     315       14808 :         mpz_sub_ui(TOMPZ(w), TOMPZ(a), b);
     316             : 
     317       14808 :         return 0;
     318             : }
     319             : 
     320             : static int
     321           0 : wrap_nettle_mpi_mul_ui(bigint_t w, const bigint_t a, unsigned long b)
     322             : {
     323           0 :         mpz_mul_ui(TOMPZ(w), TOMPZ(a), b);
     324             : 
     325           0 :         return 0;
     326             : }
     327             : 
     328           0 : static int wrap_nettle_prime_check(bigint_t pp)
     329             : {
     330           0 :         int ret;
     331             : 
     332           0 :         ret = mpz_probab_prime_p(TOMPZ(pp), PRIME_CHECK_PARAM);
     333           0 :         if (ret > 0) {
     334           0 :                 return 0;
     335             :         }
     336             : 
     337             :         return GNUTLS_E_INTERNAL_ERROR; /* ignored */
     338             : }
     339             : 
     340             : 
     341             : 
     342             : int crypto_bigint_prio = INT_MAX;
     343             : 
     344             : gnutls_crypto_bigint_st _gnutls_mpi_ops = {
     345             :         .bigint_init = wrap_nettle_mpi_init,
     346             :         .bigint_init_multi = wrap_nettle_mpi_init_multi,
     347             :         .bigint_cmp = wrap_nettle_mpi_cmp,
     348             :         .bigint_cmp_ui = wrap_nettle_mpi_cmp_ui,
     349             :         .bigint_modm = wrap_nettle_mpi_modm,
     350             :         .bigint_copy = wrap_nettle_mpi_copy,
     351             :         .bigint_set = wrap_nettle_mpi_set,
     352             :         .bigint_set_ui = wrap_nettle_mpi_set_ui,
     353             :         .bigint_get_nbits = wrap_nettle_mpi_get_nbits,
     354             :         .bigint_powm = wrap_nettle_mpi_powm,
     355             :         .bigint_addm = wrap_nettle_mpi_addm,
     356             :         .bigint_subm = wrap_nettle_mpi_subm,
     357             :         .bigint_add = wrap_nettle_mpi_add,
     358             :         .bigint_sub = wrap_nettle_mpi_sub,
     359             :         .bigint_add_ui = wrap_nettle_mpi_add_ui,
     360             :         .bigint_sub_ui = wrap_nettle_mpi_sub_ui,
     361             :         .bigint_mul = wrap_nettle_mpi_mul,
     362             :         .bigint_mulm = wrap_nettle_mpi_mulm,
     363             :         .bigint_mul_ui = wrap_nettle_mpi_mul_ui,
     364             :         .bigint_div = wrap_nettle_mpi_div,
     365             :         .bigint_prime_check = wrap_nettle_prime_check,
     366             :         .bigint_release = wrap_nettle_mpi_release,
     367             :         .bigint_clear = wrap_nettle_mpi_clear,
     368             :         .bigint_print = wrap_nettle_mpi_print,
     369             :         .bigint_scan = wrap_nettle_mpi_scan,
     370             : };

Generated by: LCOV version 1.14