str[n]casecmp => OPENSSL_strncasecmp
[openssl.git] / crypto / ffc / ffc_dh.c
1 /*
2  * Copyright 2020-2021 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 #include "internal/ffc.h"
11 #include "internal/nelem.h"
12 #include "crypto/bn_dh.h"
13
14 #ifndef OPENSSL_NO_DH
15
16 # define FFDHE(sz) {                                                        \
17         SN_ffdhe##sz, NID_ffdhe##sz,                                        \
18         sz,                                                                 \
19         &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q,             \
20         &ossl_bignum_const_2,                                               \
21     }
22
23 # define MODP(sz)  {                                                        \
24         SN_modp_##sz, NID_modp_##sz,                                        \
25         sz,                                                                 \
26         &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q,             \
27         &ossl_bignum_const_2                                                \
28     }
29
30 # define RFC5114(name, uid, sz, tag) {                                      \
31         name, uid,                                                          \
32         sz,                                                                 \
33         &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q,                 \
34         &ossl_bignum_dh##tag##_g                                            \
35     }
36
37 #else
38
39 # define FFDHE(sz)                      { SN_ffdhe##sz, NID_ffdhe##sz }
40 # define MODP(sz)                       { SN_modp_##sz, NID_modp_##sz }
41 # define RFC5114(name, uid, sz, tag)    { name, uid }
42
43 #endif
44
45 struct dh_named_group_st {
46     const char *name;
47     int uid;
48 #ifndef OPENSSL_NO_DH
49     int32_t nbits;
50     const BIGNUM *p;
51     const BIGNUM *q;
52     const BIGNUM *g;
53 #endif
54 };
55
56 static const DH_NAMED_GROUP dh_named_groups[] = {
57     FFDHE(2048),
58     FFDHE(3072),
59     FFDHE(4096),
60     FFDHE(6144),
61     FFDHE(8192),
62 #ifndef FIPS_MODULE
63     MODP(1536),
64 #endif
65     MODP(2048),
66     MODP(3072),
67     MODP(4096),
68     MODP(6144),
69     MODP(8192),
70     /*
71      * Additional dh named groups from RFC 5114 that have a different g.
72      * The uid can be any unique identifier.
73      */
74 #ifndef FIPS_MODULE
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
79 };
80
81 const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name)
82 {
83     size_t i;
84
85     for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
86         if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0)
87             return &dh_named_groups[i];
88     }
89     return NULL;
90 }
91
92 const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid)
93 {
94     size_t i;
95
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];
99     }
100     return NULL;
101 }
102
103 #ifndef OPENSSL_NO_DH
104 const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p,
105                                                          const BIGNUM *q,
106                                                          const BIGNUM *g)
107 {
108     size_t i;
109
110     for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
111         /* Keep searching until a matching p and g is found */
112         if (BN_cmp(p, dh_named_groups[i].p) == 0
113             && BN_cmp(g, dh_named_groups[i].g) == 0
114             /* Verify q is correct if it exists */
115             && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0))
116             return &dh_named_groups[i];
117     }
118     return NULL;
119 }
120 #endif
121
122 int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group)
123 {
124     if (group == NULL)
125         return NID_undef;
126     return group->uid;
127 }
128
129 const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group)
130 {
131     if (group == NULL)
132         return NULL;
133     return group->name;
134 }
135
136 #ifndef OPENSSL_NO_DH
137 const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group)
138 {
139     if (group == NULL)
140         return NULL;
141     return group->q;
142 }
143
144 int ossl_ffc_named_group_set_pqg(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group)
145 {
146     if (ffc == NULL || group == NULL)
147         return 0;
148
149     ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q,
150                              (BIGNUM *)group->g);
151
152     /* flush the cached nid, The DH layer is responsible for caching */
153     ffc->nid = NID_undef;
154     return 1;
155 }
156 #endif