]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_group_params.c
Rename FIPS_MODE to FIPS_MODULE
[thirdparty/openssl.git] / crypto / dh / dh_group_params.c
CommitLineData
ca2bf555
SL
1/*
2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/* DH parameters from RFC7919 and RFC3526 */
11
ada66e78
P
12/*
13 * DH low level APIs are deprecated for public use, but still ok for
14 * internal use.
15 */
16#include "internal/deprecated.h"
17
ca2bf555
SL
18#include <stdio.h>
19#include "internal/cryptlib.h"
7165593c 20#include "internal/ffc.h"
ca2bf555
SL
21#include "dh_local.h"
22#include <openssl/bn.h>
23#include <openssl/objects.h>
24#include "crypto/bn_dh.h"
8083fd3a 25#include "crypto/dh.h"
b03ec3b5 26#include "e_os.h" /* strcasecmp */
55f02cb6 27
7165593c
SL
28#define FFDHE(sz) { \
29 SN_ffdhe##sz, NID_ffdhe##sz, \
30 sz, \
738ee181 31 &_bignum_ffdhe##sz##_p, &_bignum_ffdhe##sz##_q, &_bignum_const_2 \
7165593c
SL
32}
33
34#define MODP(sz) { \
35 SN_modp_##sz, NID_modp_##sz, \
36 sz, \
738ee181 37 &_bignum_modp_##sz##_p, &_bignum_modp_##sz##_q, &_bignum_const_2 \
7165593c 38}
55f02cb6 39
7165593c
SL
40#define RFC5114(name, uid, sz, tag) { \
41 name, uid, \
42 sz, \
43 &_bignum_dh##tag##_p, &_bignum_dh##tag##_q, &_bignum_dh##tag##_g \
44}
55f02cb6 45
7165593c 46typedef struct dh_named_group_st {
b03ec3b5 47 const char *name;
7165593c 48 int uid;
55f02cb6
SL
49 int32_t nbits;
50 const BIGNUM *p;
7165593c
SL
51 const BIGNUM *q;
52 const BIGNUM *g;
53} DH_NAMED_GROUP;
54
55f02cb6 55
7165593c 56static const DH_NAMED_GROUP dh_named_groups[] = {
55f02cb6
SL
57 FFDHE(2048),
58 FFDHE(3072),
59 FFDHE(4096),
60 FFDHE(6144),
61 FFDHE(8192),
f844f9eb 62#ifndef FIPS_MODULE
55f02cb6
SL
63 MODP(1536),
64#endif
65 MODP(2048),
66 MODP(3072),
67 MODP(4096),
68 MODP(6144),
69 MODP(8192),
7165593c
SL
70 /*
71 * Additional dh named groups from RFC 5114 that have a different g.
72 * The uid can be any unique identifier.
73 */
f844f9eb 74#ifndef FIPS_MODULE
7165593c
SL
75 RFC5114("dh_1024_160", 1, 1024, 1024_160),
76 RFC5114("dh_2048_224", 2, 2048, 2048_224),
77 RFC5114("dh_2048_256", 3, 2048, 2048_256),
78#endif
55f02cb6 79};
ca2bf555 80
7165593c 81int ffc_named_group_to_uid(const char *name)
b03ec3b5
SL
82{
83 size_t i;
84
7165593c
SL
85 for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
86 if (strcasecmp(dh_named_groups[i].name, name) == 0)
87 return dh_named_groups[i].uid;
b03ec3b5
SL
88 }
89 return NID_undef;
90}
91
7165593c 92const char *ffc_named_group_from_uid(int uid)
b03ec3b5
SL
93{
94 size_t i;
95
7165593c
SL
96 for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
97 if (dh_named_groups[i].uid == uid)
98 return dh_named_groups[i].name;
b03ec3b5
SL
99 }
100 return NULL;
101}
102
7165593c 103static DH *dh_param_init(OPENSSL_CTX *libctx, int uid, const BIGNUM *p,
738ee181 104 const BIGNUM *q, const BIGNUM *g)
ca2bf555 105{
7165593c 106 DH *dh = dh_new_with_libctx(libctx);
ca2bf555
SL
107
108 if (dh == NULL)
109 return NULL;
110
7165593c 111 dh->params.nid = uid;
ca2bf555 112 dh->params.p = (BIGNUM *)p;
738ee181 113 dh->params.q = (BIGNUM *)q;
7165593c 114 dh->params.g = (BIGNUM *)g;
738ee181 115 dh->length = BN_num_bits(q);
ca2bf555
SL
116 dh->dirty_cnt++;
117 return dh;
118}
119
7165593c 120static DH *dh_new_by_group_name(OPENSSL_CTX *libctx, const char *name)
ca2bf555 121{
55f02cb6
SL
122 int i;
123
7165593c
SL
124 if (name == NULL)
125 return NULL;
126
127 for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
128 if (strcasecmp(dh_named_groups[i].name, name) == 0) {
7165593c
SL
129 return dh_param_init(libctx, dh_named_groups[i].uid,
130 dh_named_groups[i].p,
131 dh_named_groups[i].q,
738ee181 132 dh_named_groups[i].g);
55f02cb6 133 }
ca2bf555 134 }
55f02cb6
SL
135 DHerr(0, DH_R_INVALID_PARAMETER_NID);
136 return NULL;
ca2bf555
SL
137}
138
7165593c
SL
139DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid)
140{
141 const char *name = ffc_named_group_from_uid(nid);
142
143 return dh_new_by_group_name(libctx, name);
144}
145
8083fd3a
SL
146DH *DH_new_by_nid(int nid)
147{
7165593c
SL
148 return dh_new_by_nid_with_libctx(NULL, nid);
149}
150
151int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name)
152{
153 int i;
154 BIGNUM *q = NULL;
155
156 if (ffc == NULL)
157 return 0;
158
159 for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
160 if (strcasecmp(dh_named_groups[i].name, group_name) == 0) {
738ee181
SL
161 ffc_params_set0_pqg(ffc,
162 (BIGNUM *)dh_named_groups[i].p,
163 (BIGNUM *)dh_named_groups[i].q,
164 (BIGNUM *)dh_named_groups[i].g);
7165593c
SL
165 /* flush the cached nid, The DH layer is responsible for caching */
166 ffc->nid = NID_undef;
167 return 1;
168 }
169 }
170 /* gets here on error or if the name was not found */
171 BN_free(q);
172 return 0;
8083fd3a 173}
8083fd3a 174
738ee181 175void dh_cache_named_group(DH *dh)
ca2bf555 176{
738ee181 177 int i;
55f02cb6
SL
178
179 if (dh == NULL)
738ee181
SL
180 return;
181
182 dh->params.nid = NID_undef; /* flush cached value */
ca2bf555 183
738ee181
SL
184 /* Exit if p or g is not set */
185 if (dh->params.p == NULL
186 || dh->params.g == NULL)
187 return;
ca2bf555 188
7165593c 189 for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
738ee181
SL
190 /* Keep searching until a matching p and g is found */
191 if (BN_cmp(dh->params.p, dh_named_groups[i].p) == 0
192 && BN_cmp(dh->params.g, dh_named_groups[i].g) == 0) {
193 /* Verify q is correct if it exists */
194 if (dh->params.q != NULL) {
195 if (BN_cmp(dh->params.q, dh_named_groups[i].q) != 0)
196 continue; /* ignore if q does not match */
197 } else {
198 dh->params.q = (BIGNUM *)dh_named_groups[i].q;
199 }
200 dh->params.nid = dh_named_groups[i].uid; /* cache the nid */
201 dh->length = BN_num_bits(dh->params.q);
202 dh->dirty_cnt++;
203 break;
55f02cb6 204 }
ca2bf555 205 }
738ee181
SL
206}
207
208int DH_get_nid(const DH *dh)
209{
210 if (dh == NULL)
211 return NID_undef;
212
213 return dh->params.nid;
ca2bf555 214}