LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - mpi.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 177 233 76.0 %
Date: 2020-10-30 04:50:48 Functions: 17 17 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001-2012 Free Software Foundation, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS 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, libgcrypt and
      24             :  * other stuff that didn't fit anywhere else.
      25             :  */
      26             : 
      27             : #include "gnutls_int.h"
      28             : #include <libtasn1.h>
      29             : #include "errors.h"
      30             : #include <num.h>
      31             : #include <mpi.h>
      32             : #include <random.h>
      33             : #include <x509/x509_int.h>
      34             : 
      35             : /* Functions that refer to the mpi library.
      36             :  */
      37             : 
      38             : /* Returns a random number r, 0 < r < p */
      39             : bigint_t
      40         288 : _gnutls_mpi_random_modp(bigint_t r, bigint_t p,
      41             :                       gnutls_rnd_level_t level)
      42             : {
      43         288 :         size_t size;
      44         288 :         int ret;
      45         288 :         bigint_t tmp;
      46         288 :         uint8_t tmpbuf[512];
      47         288 :         uint8_t *buf;
      48         288 :         int buf_release = 0;
      49             :         
      50         288 :         size = ((_gnutls_mpi_get_nbits(p)+64)/8) + 1;
      51             : 
      52         288 :         if (size < sizeof(tmpbuf)) {
      53             :                 buf = tmpbuf;
      54             :         } else {
      55          11 :                 buf = gnutls_malloc(size);
      56          11 :                 if (buf == NULL) {
      57           0 :                         gnutls_assert();
      58           0 :                         goto cleanup;
      59             :                 }
      60             :                 buf_release = 1;
      61             :         }
      62             : 
      63         288 :         ret = gnutls_rnd(level, buf, size);
      64         288 :         if (ret < 0) {
      65           0 :                 gnutls_assert();
      66           0 :                 goto cleanup;
      67             :         }
      68             :         
      69         288 :         ret = _gnutls_mpi_init_scan(&tmp, buf, size);
      70         288 :         if (ret < 0) {
      71           0 :                 gnutls_assert();
      72           0 :                 goto cleanup;
      73             :         }
      74             :         
      75         288 :         ret = _gnutls_mpi_modm(tmp, tmp, p);
      76         288 :         if (ret < 0) {
      77           0 :                 gnutls_assert();
      78           0 :                 goto cleanup;
      79             :         }
      80             : 
      81         288 :         if (_gnutls_mpi_cmp_ui(tmp, 0) == 0) {
      82           0 :                 ret = _gnutls_mpi_add_ui(tmp, tmp, 1);
      83           0 :                 if (ret < 0) {
      84           0 :                         gnutls_assert();
      85           0 :                         goto cleanup;
      86             :                 }
      87             :         }
      88             : 
      89         288 :         if (buf_release != 0) {
      90          11 :                 gnutls_free(buf);
      91             :         }
      92             : 
      93         288 :         if (r != NULL) {
      94         288 :                 ret = _gnutls_mpi_set(r, tmp);
      95         288 :                 if (ret < 0)
      96           0 :                         goto cleanup;
      97             : 
      98         288 :                 _gnutls_mpi_release(&tmp);
      99         288 :                 return r;
     100             :         }
     101             : 
     102           0 :         return tmp;
     103             : 
     104           0 :       cleanup:
     105           0 :         if (buf_release != 0)
     106           0 :                 gnutls_free(buf);
     107             :         return NULL;
     108             : }
     109             : 
     110             : /* returns %GNUTLS_E_SUCCESS (0) on success
     111             :  */
     112      177690 : int _gnutls_mpi_init_scan(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
     113             : {
     114      177690 : bigint_t r;
     115      177690 : int ret;
     116             : 
     117      177690 :         ret = _gnutls_mpi_init(&r);
     118      177690 :         if (ret < 0)
     119           0 :                 return gnutls_assert_val(ret);
     120             : 
     121      177690 :         ret =
     122      177690 :             _gnutls_mpi_scan(r, buffer, nbytes);
     123      177690 :         if (ret < 0) {
     124           0 :                 gnutls_assert();
     125           0 :                 _gnutls_mpi_release(&r);
     126           0 :                 return ret;
     127             :         }
     128             : 
     129      177690 :         *ret_mpi = r;
     130             : 
     131      177690 :         return 0;
     132             : }
     133             : 
     134             : /* returns %GNUTLS_E_SUCCESS (0) on success. Fails if the number is zero.
     135             :  */
     136             : int
     137       32119 : _gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
     138             : {
     139       32119 :         int ret;
     140             : 
     141       32119 :         ret = _gnutls_mpi_init_scan(ret_mpi, buffer, nbytes);
     142       32119 :         if (ret < 0)
     143             :                 return ret;
     144             : 
     145             :         /* MPIs with 0 bits are illegal
     146             :          */
     147       32119 :         if (_gnutls_mpi_cmp_ui(*ret_mpi, 0) == 0) {
     148          21 :                 _gnutls_mpi_release(ret_mpi);
     149          21 :                 return GNUTLS_E_MPI_SCAN_FAILED;
     150             :         }
     151             : 
     152             :         return 0;
     153             : }
     154             : 
     155             : int
     156        1076 : _gnutls_mpi_init_scan_le(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
     157             : {
     158        1076 :         bigint_t r;
     159        1076 :         int ret;
     160             : 
     161        1076 :         ret = _gnutls_mpi_init(&r);
     162        1076 :         if (ret < 0)
     163           0 :                 return gnutls_assert_val(ret);
     164             : 
     165        1076 :         ret = _gnutls_mpi_scan_le(r, buffer, nbytes);
     166        1076 :         if (ret < 0) {
     167           0 :                 gnutls_assert();
     168           0 :                 _gnutls_mpi_release(&r);
     169           0 :                 return ret;
     170             :         }
     171             : 
     172        1076 :         *ret_mpi = r;
     173             : 
     174        1076 :         return 0;
     175             : }
     176             : 
     177          91 : int _gnutls_mpi_dprint_le(const bigint_t a, gnutls_datum_t * dest)
     178             : {
     179          91 :         int ret;
     180          91 :         uint8_t *buf = NULL;
     181          91 :         size_t bytes = 0;
     182             : 
     183          91 :         if (dest == NULL || a == NULL)
     184             :                 return GNUTLS_E_INVALID_REQUEST;
     185             : 
     186          91 :         _gnutls_mpi_print_le(a, NULL, &bytes);
     187          91 :         if (bytes != 0)
     188          91 :                 buf = gnutls_malloc(bytes);
     189          91 :         if (buf == NULL)
     190           0 :                 return GNUTLS_E_MEMORY_ERROR;
     191             : 
     192          91 :         ret = _gnutls_mpi_print_le(a, buf, &bytes);
     193          91 :         if (ret < 0) {
     194           0 :                 gnutls_free(buf);
     195           0 :                 return ret;
     196             :         }
     197             : 
     198          91 :         dest->data = buf;
     199          91 :         dest->size = bytes;
     200          91 :         return 0;
     201             : }
     202             : 
     203             : /* Always has the first bit zero */
     204        7844 : int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest)
     205             : {
     206        7844 :         int ret;
     207        7844 :         uint8_t *buf = NULL;
     208        7844 :         size_t bytes = 0;
     209             : 
     210        7844 :         if (dest == NULL || a == NULL)
     211             :                 return GNUTLS_E_INVALID_REQUEST;
     212             : 
     213        7844 :         _gnutls_mpi_print_lz(a, NULL, &bytes);
     214             : 
     215        7844 :         if (bytes != 0)
     216        7844 :                 buf = gnutls_malloc(bytes);
     217        7844 :         if (buf == NULL)
     218           0 :                 return GNUTLS_E_MEMORY_ERROR;
     219             : 
     220        7844 :         ret = _gnutls_mpi_print_lz(a, buf, &bytes);
     221        7844 :         if (ret < 0) {
     222           0 :                 gnutls_free(buf);
     223           0 :                 return ret;
     224             :         }
     225             : 
     226        7844 :         dest->data = buf;
     227        7844 :         dest->size = bytes;
     228        7844 :         return 0;
     229             : }
     230             : 
     231       11336 : int _gnutls_mpi_dprint(const bigint_t a, gnutls_datum_t * dest)
     232             : {
     233       11336 :         int ret;
     234       11336 :         uint8_t *buf = NULL;
     235       11336 :         size_t bytes = 0;
     236             : 
     237       11336 :         if (dest == NULL || a == NULL)
     238             :                 return GNUTLS_E_INVALID_REQUEST;
     239             : 
     240       11336 :         _gnutls_mpi_print(a, NULL, &bytes);
     241       11336 :         if (bytes != 0)
     242       11336 :                 buf = gnutls_malloc(bytes);
     243       11336 :         if (buf == NULL)
     244           0 :                 return GNUTLS_E_MEMORY_ERROR;
     245             : 
     246       11336 :         ret = _gnutls_mpi_print(a, buf, &bytes);
     247       11336 :         if (ret < 0) {
     248           0 :                 gnutls_free(buf);
     249           0 :                 return ret;
     250             :         }
     251             : 
     252       11336 :         dest->data = buf;
     253       11336 :         dest->size = bytes;
     254       11336 :         return 0;
     255             : }
     256             : 
     257             : /* This function will copy the mpi data into a datum,
     258             :  * but will set minimum size to 'size'. That means that
     259             :  * the output value is left padded with zeros.
     260             :  */
     261             : int
     262       14112 : _gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest,
     263             :                         size_t size)
     264             : {
     265       14112 :         int ret;
     266       14112 :         uint8_t *buf = NULL;
     267       14112 :         size_t bytes = 0;
     268       14112 :         unsigned int i;
     269             : 
     270       14112 :         if (dest == NULL || a == NULL)
     271             :                 return GNUTLS_E_INVALID_REQUEST;
     272             : 
     273       14112 :         _gnutls_mpi_print(a, NULL, &bytes);
     274       14112 :         if (bytes != 0)
     275       14112 :                 buf = gnutls_malloc(MAX(size, bytes));
     276       14112 :         if (buf == NULL)
     277           0 :                 return GNUTLS_E_MEMORY_ERROR;
     278             : 
     279       14112 :         if (bytes <= size) {
     280       14112 :                 size_t diff = size - bytes;
     281       14155 :                 for (i = 0; i < diff; i++)
     282          43 :                         buf[i] = 0;
     283       14112 :                 ret = _gnutls_mpi_print(a, &buf[diff], &bytes);
     284             :         } else {
     285           0 :                 ret = _gnutls_mpi_print(a, buf, &bytes);
     286             :         }
     287             : 
     288       14112 :         if (ret < 0) {
     289           0 :                 gnutls_free(buf);
     290           0 :                 return ret;
     291             :         }
     292             : 
     293       14112 :         dest->data = buf;
     294       14112 :         dest->size = MAX(size, bytes);
     295       14112 :         return 0;
     296             : }
     297             : 
     298             : /* like _gnutls_mpi_dprint_size, but prints into preallocated byte buffer */
     299             : int
     300        1098 : _gnutls_mpi_bprint_size(const bigint_t a, uint8_t *buf, size_t size)
     301             : {
     302        1098 :         int result;
     303        1098 :         size_t bytes = 0;
     304             : 
     305        1098 :         result = _gnutls_mpi_print(a, NULL, &bytes);
     306        1098 :         if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
     307           0 :                 return gnutls_assert_val(result);
     308             : 
     309        1098 :         if (bytes <= size) {
     310        1098 :                 unsigned i;
     311        1098 :                 size_t diff = size - bytes;
     312             : 
     313        1109 :                 for (i = 0; i < diff; i++)
     314          11 :                         buf[i] = 0;
     315        1098 :                 result = _gnutls_mpi_print(a, &buf[diff], &bytes);
     316             :         } else {
     317           0 :                 result = _gnutls_mpi_print(a, buf, &bytes);
     318             :         }
     319             : 
     320             :         return result;
     321             : }
     322             : 
     323             : /* Flags for __gnutls_x509_read_int() and __gnutls_x509_write_int */
     324             : #define GNUTLS_X509_INT_OVERWRITE       (1 << 0)
     325             : #define GNUTLS_X509_INT_LE              (1 << 1)
     326             : #define GNUTLS_X509_INT_LZ              (1 << 2) /* write only */
     327             : 
     328             : /* this function reads an integer
     329             :  * from asn1 structs. Combines the read and mpi_scan
     330             :  * steps.
     331             :  */
     332             : static int
     333      112493 : __gnutls_x509_read_int(ASN1_TYPE node, const char *value,
     334             :                        bigint_t * ret_mpi, unsigned int flags)
     335             : {
     336      112493 :         int result;
     337      112493 :         uint8_t *tmpstr = NULL;
     338      112493 :         int tmpstr_size;
     339             : 
     340      112493 :         tmpstr_size = 0;
     341      112493 :         result = asn1_read_value(node, value, NULL, &tmpstr_size);
     342      112493 :         if (result != ASN1_MEM_ERROR) {
     343          48 :                 gnutls_assert();
     344          48 :                 return _gnutls_asn2err(result);
     345             :         }
     346             : 
     347      112445 :         tmpstr = gnutls_malloc(tmpstr_size);
     348      112445 :         if (tmpstr == NULL) {
     349           0 :                 gnutls_assert();
     350           0 :                 return GNUTLS_E_MEMORY_ERROR;
     351             :         }
     352             : 
     353      112445 :         result = asn1_read_value(node, value, tmpstr, &tmpstr_size);
     354      112445 :         if (result != ASN1_SUCCESS) {
     355           0 :                 gnutls_assert();
     356           0 :                 gnutls_free(tmpstr);
     357           0 :                 return _gnutls_asn2err(result);
     358             :         }
     359             : 
     360      112445 :         if (flags & GNUTLS_X509_INT_LE)
     361          42 :                 result = _gnutls_mpi_init_scan_le(ret_mpi, tmpstr,
     362             :                                                   tmpstr_size);
     363             :         else
     364      112403 :                 result = _gnutls_mpi_init_scan(ret_mpi, tmpstr,
     365             :                                                tmpstr_size);
     366             : 
     367      112445 :         if (flags & GNUTLS_X509_INT_OVERWRITE)
     368       32282 :                 zeroize_key(tmpstr, tmpstr_size);
     369      112445 :         gnutls_free(tmpstr);
     370             : 
     371      112445 :         if (result < 0) {
     372           0 :                 gnutls_assert();
     373           0 :                 return result;
     374             :         }
     375             : 
     376             :         return 0;
     377             : }
     378             : 
     379             : int
     380       80196 : _gnutls_x509_read_int(ASN1_TYPE node, const char *value,
     381             :                       bigint_t * ret_mpi)
     382             : {
     383       80196 :         return __gnutls_x509_read_int(node, value, ret_mpi,
     384             :                                       0);
     385             : }
     386             : 
     387             : int
     388       32255 : _gnutls_x509_read_key_int(ASN1_TYPE node, const char *value,
     389             :                       bigint_t * ret_mpi)
     390             : {
     391       32255 :         return __gnutls_x509_read_int(node, value, ret_mpi,
     392             :                                       GNUTLS_X509_INT_OVERWRITE);
     393             : }
     394             : 
     395             : int
     396          42 : _gnutls_x509_read_key_int_le(ASN1_TYPE node, const char *value,
     397             :                              bigint_t * ret_mpi)
     398             : {
     399          42 :         return __gnutls_x509_read_int(node, value, ret_mpi,
     400             :                                       GNUTLS_X509_INT_OVERWRITE |
     401             :                                       GNUTLS_X509_INT_LE);
     402             : }
     403             : 
     404             : /* Writes the specified integer into the specified node.
     405             :  */
     406             : static int
     407       19058 : __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi,
     408             :                         unsigned int flags)
     409             : {
     410       19058 :         uint8_t *tmpstr;
     411       19058 :         size_t s_len;
     412       19058 :         int result;
     413             : 
     414       19058 :         s_len = 0;
     415       19058 :         if (flags & GNUTLS_X509_INT_LZ)
     416       18528 :                 result = _gnutls_mpi_print_lz(mpi, NULL, &s_len);
     417         530 :         else if (GNUTLS_X509_INT_LE)
     418         530 :                 result = _gnutls_mpi_print_le(mpi, NULL, &s_len);
     419             :         else
     420             :                 result = _gnutls_mpi_print(mpi, NULL, &s_len);
     421             : 
     422       19058 :         if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
     423           0 :                 gnutls_assert();
     424           0 :                 return result;
     425             :         }
     426             : 
     427       19058 :         tmpstr = gnutls_malloc(s_len);
     428       19058 :         if (tmpstr == NULL) {
     429           0 :                 gnutls_assert();
     430           0 :                 return GNUTLS_E_MEMORY_ERROR;
     431             :         }
     432             : 
     433       19058 :         if (flags & GNUTLS_X509_INT_LZ)
     434       18528 :                 result = _gnutls_mpi_print_lz(mpi, tmpstr, &s_len);
     435         530 :         else if (GNUTLS_X509_INT_LE)
     436         530 :                 result = _gnutls_mpi_print_le(mpi, tmpstr, &s_len);
     437             :         else
     438             :                 result = _gnutls_mpi_print(mpi, tmpstr, &s_len);
     439             : 
     440       19058 :         if (result != 0) {
     441           0 :                 gnutls_assert();
     442           0 :                 gnutls_free(tmpstr);
     443           0 :                 return GNUTLS_E_MPI_PRINT_FAILED;
     444             :         }
     445             : 
     446       19058 :         result = asn1_write_value(node, value, tmpstr, s_len);
     447             : 
     448       19058 :         if (flags & GNUTLS_X509_INT_OVERWRITE)
     449        3138 :                 zeroize_key(tmpstr, s_len);
     450             : 
     451       19058 :         gnutls_free(tmpstr);
     452             : 
     453       19058 :         if (result != ASN1_SUCCESS) {
     454           0 :                 gnutls_assert();
     455           0 :                 return _gnutls_asn2err(result);
     456             :         }
     457             : 
     458             :         return 0;
     459             : }
     460             : 
     461             : int
     462       15920 : _gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi,
     463             :                        int lz)
     464             : {
     465       15920 :         return __gnutls_x509_write_int(node, value, mpi,
     466             :                                        lz ? GNUTLS_X509_INT_LZ : 0);
     467             : }
     468             : 
     469             : int
     470        2608 : _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi,
     471             :                        int lz)
     472             : {
     473        2608 :         return __gnutls_x509_write_int(node, value, mpi,
     474             :                                        (lz ? GNUTLS_X509_INT_LZ : 0) |
     475             :                                        GNUTLS_X509_INT_OVERWRITE);
     476             : }
     477             : 
     478             : int
     479         530 : _gnutls_x509_write_key_int_le(ASN1_TYPE node, const char *value, bigint_t mpi)
     480             : {
     481         530 :         return __gnutls_x509_write_int(node, value, mpi,
     482             :                                        GNUTLS_X509_INT_OVERWRITE |
     483             :                                        GNUTLS_X509_INT_LE);
     484             : }

Generated by: LCOV version 1.14