Line data Source code
1 : /* 2 : * Copyright (C) 2011-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 : /* Helper functions for ECC handling 24 : * based on public domain code by Tom St. Dennis. 25 : */ 26 : #include "gnutls_int.h" 27 : #include <mpi.h> 28 : #include <ecc.h> 29 : #include <algorithms.h> 30 : #include "errors.h" 31 : 32 : int 33 7037 : _gnutls_ecc_ansi_x962_export(gnutls_ecc_curve_t curve, bigint_t x, 34 : bigint_t y, gnutls_datum_t * out) 35 : { 36 7037 : int numlen = gnutls_ecc_curve_get_size(curve); 37 7037 : int byte_size, ret; 38 7037 : size_t size; 39 : 40 7037 : if (numlen == 0) 41 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); 42 : 43 7037 : out->size = 1 + 2 * numlen; 44 : 45 7037 : out->data = gnutls_malloc(out->size); 46 7037 : if (out->data == NULL) 47 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); 48 : 49 7037 : memset(out->data, 0, out->size); 50 : 51 : /* store byte 0x04 */ 52 7037 : out->data[0] = 0x04; 53 : 54 : /* pad and store x */ 55 7037 : byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8; 56 7037 : if (numlen < byte_size) { 57 1 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); 58 1 : goto cleanup; 59 : } 60 : 61 7036 : size = out->size - (1 + (numlen - byte_size)); 62 7036 : ret = 63 7036 : _gnutls_mpi_print(x, &out->data[1 + (numlen - byte_size)], 64 : &size); 65 7036 : if (ret < 0) { 66 0 : gnutls_assert(); 67 0 : goto cleanup; 68 : } 69 : 70 7036 : byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8; 71 7036 : if (numlen < byte_size) { 72 0 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); 73 0 : goto cleanup; 74 : } 75 : 76 7036 : size = out->size - (1 + (numlen + numlen - byte_size)); 77 7036 : ret = 78 7036 : _gnutls_mpi_print(y, 79 : &out->data[1 + numlen + numlen - byte_size], 80 : &size); 81 7036 : if (ret < 0) { 82 0 : gnutls_assert(); 83 0 : goto cleanup; 84 : } 85 : 86 : /* pad and store y */ 87 : return 0; 88 1 : cleanup: 89 1 : _gnutls_free_datum(out); 90 : return ret; 91 : } 92 : 93 : 94 : 95 : int 96 15074 : _gnutls_ecc_ansi_x962_import(const uint8_t * in, 97 : unsigned long inlen, bigint_t * x, 98 : bigint_t * y) 99 : { 100 15074 : int ret; 101 : 102 : /* must be odd */ 103 15074 : if ((inlen & 1) == 0) { 104 : return GNUTLS_E_INVALID_REQUEST; 105 : } 106 : 107 : /* check for 4 */ 108 15067 : if (in[0] != 4) { 109 9 : return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); 110 : } 111 : 112 : /* read data */ 113 15058 : ret = _gnutls_mpi_init_scan(x, in + 1, (inlen - 1) >> 1); 114 15058 : if (ret < 0) 115 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); 116 : 117 15058 : ret = 118 15058 : _gnutls_mpi_init_scan(y, in + 1 + ((inlen - 1) >> 1), 119 : (inlen - 1) >> 1); 120 15058 : if (ret < 0) { 121 0 : _gnutls_mpi_release(x); 122 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); 123 : } 124 : 125 : return 0; 126 : } 127 :