Coverage Report

Created: 2025-03-18 06:55

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