Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/algorithms/secparams.c
Line
Count
Source (jump to first uncovered line)
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
#include "gnutls_int.h"
24
#include <algorithms.h>
25
#include "errors.h"
26
#include <x509/common.h>
27
28
typedef struct {
29
  const char *name;
30
  gnutls_sec_param_t sec_param;
31
  unsigned int bits;  /* security level */
32
  unsigned int pk_bits; /* DH, RSA, SRP */
33
  unsigned int dsa_bits;  /* bits for DSA. Handled differently since
34
         * choice of key size in DSA is political.
35
         */
36
  unsigned int subgroup_bits; /* subgroup bits */
37
  unsigned int ecc_bits;  /* bits for ECC keys */
38
} gnutls_sec_params_entry;
39
40
static const gnutls_sec_params_entry sec_params[] = {
41
  {"Insecure", GNUTLS_SEC_PARAM_INSECURE, 0, 0, 0, 0, 0},
42
  {"Export", GNUTLS_SEC_PARAM_EXPORT, 42, 512, 0, 84, 0},
43
  {"Very weak", GNUTLS_SEC_PARAM_VERY_WEAK, 64, 767, 0, 128, 0},
44
  {"Weak", GNUTLS_SEC_PARAM_WEAK, 72, 1008, 1008, 160, 160},
45
#ifdef ENABLE_FIPS140
46
  {"Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160},
47
  {"Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1024, 1024, 192, 192},
48
  {"Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 224, 224},
49
  {"High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256},
50
#else
51
  {"Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160},  /* ENISA-LEGACY */
52
  {"Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1776, 2048, 192, 192},
53
  {"Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 256, 224},
54
  {"High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256},
55
#endif
56
  {"Ultra", GNUTLS_SEC_PARAM_ULTRA, 192, 8192, 8192, 384, 384},
57
  {"Future", GNUTLS_SEC_PARAM_FUTURE, 256, 15360, 15360, 512, 512},
58
  {NULL, 0, 0, 0, 0, 0}
59
};
60
61
/**
62
 * gnutls_sec_param_to_pk_bits:
63
 * @algo: is a public key algorithm
64
 * @param: is a security parameter
65
 *
66
 * When generating private and public key pairs a difficult question
67
 * is which size of "bits" the modulus will be in RSA and the group size
68
 * in DSA. The easy answer is 1024, which is also wrong. This function
69
 * will convert a human understandable security parameter to an
70
 * appropriate size for the specific algorithm.
71
 *
72
 * Returns: The number of bits, or (0).
73
 *
74
 * Since: 2.12.0
75
 **/
76
unsigned int
77
gnutls_sec_param_to_pk_bits(gnutls_pk_algorithm_t algo,
78
          gnutls_sec_param_t param)
79
0
{
80
0
  unsigned int ret = 0;
81
0
  const gnutls_sec_params_entry *p;
82
83
  /* handle DSA differently */
84
0
  for (p = sec_params; p->name; p++) {
85
0
    if (p->sec_param == param) {
86
0
      if (algo == GNUTLS_PK_DSA)
87
0
        ret = p->dsa_bits;
88
0
      else if (IS_EC(algo) || IS_GOSTEC(algo))
89
0
        ret = p->ecc_bits;
90
0
      else
91
0
        ret = p->pk_bits;
92
0
      break;
93
0
    }
94
0
  }
95
96
0
  return ret;
97
0
}
98
99
/**
100
 * gnutls_sec_param_to_symmetric_bits:
101
 * @algo: is a public key algorithm
102
 * @param: is a security parameter
103
 *
104
 * This function will return the number of bits that correspond to
105
 * symmetric cipher strength for the given security parameter.
106
 *
107
 * Returns: The number of bits, or (0).
108
 *
109
 * Since: 3.3.0
110
 **/
111
unsigned int gnutls_sec_param_to_symmetric_bits(gnutls_sec_param_t param)
112
0
{
113
0
  unsigned int ret = 0;
114
0
  const gnutls_sec_params_entry *p;
115
116
  /* handle DSA differently */
117
0
  for (p = sec_params; p->name; p++) {
118
0
    if (p->sec_param == param) {
119
0
      ret = p->bits;
120
0
      break;
121
0
    }
122
0
  }
123
124
0
  return ret;
125
0
}
126
127
/* Returns the corresponding size for subgroup bits (q),
128
 * given the group bits (p).
129
 */
130
unsigned int _gnutls_pk_bits_to_subgroup_bits(unsigned int pk_bits)
131
0
{
132
0
  unsigned int ret = 0;
133
0
  const gnutls_sec_params_entry *p;
134
135
0
  for (p = sec_params; p->name; p++) {
136
0
    ret = p->subgroup_bits;
137
0
    if (p->pk_bits >= pk_bits)
138
0
      break;
139
0
  }
140
141
0
  return ret;
142
0
}
143
144
/* Returns a corresponding SHA algorithm size for the
145
 * public key bits given. It is based on the NIST mappings.
146
 */
147
gnutls_digest_algorithm_t _gnutls_pk_bits_to_sha_hash(unsigned int pk_bits)
148
0
{
149
0
  const gnutls_sec_params_entry *p;
150
151
0
  for (p = sec_params; p->name; p++) {
152
0
    if (p->pk_bits >= pk_bits) {
153
0
      if (p->bits <= 128)
154
0
        return GNUTLS_DIG_SHA256;
155
0
      else if (p->bits <= 192)
156
0
        return GNUTLS_DIG_SHA384;
157
0
      else
158
0
        return GNUTLS_DIG_SHA512;
159
0
    }
160
0
  }
161
162
0
  return GNUTLS_DIG_SHA256;
163
0
}
164
165
/**
166
 * gnutls_sec_param_get_name:
167
 * @param: is a security parameter
168
 *
169
 * Convert a #gnutls_sec_param_t value to a string.
170
 *
171
 * Returns: a pointer to a string that contains the name of the
172
 *   specified security level, or %NULL.
173
 *
174
 * Since: 2.12.0
175
 **/
176
const char *gnutls_sec_param_get_name(gnutls_sec_param_t param)
177
0
{
178
0
  const char *ret = "Unknown";
179
0
  const gnutls_sec_params_entry *p;
180
181
0
  for (p = sec_params; p->name; p++) {
182
0
    if (p->sec_param == param) {
183
0
      ret = p->name;
184
0
      break;
185
0
    }
186
0
  }
187
188
0
  return ret;
189
0
}
190
191
/**
192
 * gnutls_pk_bits_to_sec_param:
193
 * @algo: is a public key algorithm
194
 * @bits: is the number of bits
195
 *
196
 * This is the inverse of gnutls_sec_param_to_pk_bits(). Given an algorithm
197
 * and the number of bits, it will return the security parameter. This is
198
 * a rough indication.
199
 *
200
 * Returns: The security parameter.
201
 *
202
 * Since: 2.12.0
203
 **/
204
gnutls_sec_param_t
205
gnutls_pk_bits_to_sec_param(gnutls_pk_algorithm_t algo, unsigned int bits)
206
0
{
207
0
  gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_INSECURE;
208
0
  const gnutls_sec_params_entry *p;
209
210
0
  if (bits == 0)
211
0
    return GNUTLS_SEC_PARAM_UNKNOWN;
212
213
0
  if (IS_EC(algo) || IS_GOSTEC(algo)) {
214
0
    for (p = sec_params; p->name; p++) {
215
0
      if (p->ecc_bits > bits)
216
0
        break;
217
0
      ret = p->sec_param;
218
0
    }
219
0
  } else {
220
0
    for (p = sec_params; p->name; p++) {
221
0
      if (p->pk_bits > bits)
222
0
        break;
223
0
      ret = p->sec_param;
224
0
    }
225
0
  }
226
227
0
  return ret;
228
0
}