1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "internal/ffc.h" 11e1051a39Sopenharmony_ci#include "internal/nelem.h" 12e1051a39Sopenharmony_ci#include "crypto/bn_dh.h" 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci# define FFDHE(sz, keylength) { \ 17e1051a39Sopenharmony_ci SN_ffdhe##sz, NID_ffdhe##sz, \ 18e1051a39Sopenharmony_ci sz, \ 19e1051a39Sopenharmony_ci keylength, \ 20e1051a39Sopenharmony_ci &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q, \ 21e1051a39Sopenharmony_ci &ossl_bignum_const_2, \ 22e1051a39Sopenharmony_ci } 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci# define MODP(sz, keylength) { \ 25e1051a39Sopenharmony_ci SN_modp_##sz, NID_modp_##sz, \ 26e1051a39Sopenharmony_ci sz, \ 27e1051a39Sopenharmony_ci keylength, \ 28e1051a39Sopenharmony_ci &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q, \ 29e1051a39Sopenharmony_ci &ossl_bignum_const_2 \ 30e1051a39Sopenharmony_ci } 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci# define RFC5114(name, uid, sz, tag) { \ 33e1051a39Sopenharmony_ci name, uid, \ 34e1051a39Sopenharmony_ci sz, \ 35e1051a39Sopenharmony_ci 0, \ 36e1051a39Sopenharmony_ci &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q, \ 37e1051a39Sopenharmony_ci &ossl_bignum_dh##tag##_g \ 38e1051a39Sopenharmony_ci } 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci#else 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci# define FFDHE(sz, keylength) { SN_ffdhe##sz, NID_ffdhe##sz } 43e1051a39Sopenharmony_ci# define MODP(sz, keylength) { SN_modp_##sz, NID_modp_##sz } 44e1051a39Sopenharmony_ci# define RFC5114(name, uid, sz, tag) { name, uid } 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ci#endif 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_cistruct dh_named_group_st { 49e1051a39Sopenharmony_ci const char *name; 50e1051a39Sopenharmony_ci int uid; 51e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 52e1051a39Sopenharmony_ci int32_t nbits; 53e1051a39Sopenharmony_ci int keylength; 54e1051a39Sopenharmony_ci const BIGNUM *p; 55e1051a39Sopenharmony_ci const BIGNUM *q; 56e1051a39Sopenharmony_ci const BIGNUM *g; 57e1051a39Sopenharmony_ci#endif 58e1051a39Sopenharmony_ci}; 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci/* 61e1051a39Sopenharmony_ci * The private key length values are taken from RFC7919 with the values for 62e1051a39Sopenharmony_ci * MODP primes given the same lengths as the equivalent FFDHE. 63e1051a39Sopenharmony_ci * The MODP 1536 value is approximated. 64e1051a39Sopenharmony_ci */ 65e1051a39Sopenharmony_cistatic const DH_NAMED_GROUP dh_named_groups[] = { 66e1051a39Sopenharmony_ci FFDHE(2048, 225), 67e1051a39Sopenharmony_ci FFDHE(3072, 275), 68e1051a39Sopenharmony_ci FFDHE(4096, 325), 69e1051a39Sopenharmony_ci FFDHE(6144, 375), 70e1051a39Sopenharmony_ci FFDHE(8192, 400), 71e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 72e1051a39Sopenharmony_ci MODP(1536, 200), 73e1051a39Sopenharmony_ci#endif 74e1051a39Sopenharmony_ci MODP(2048, 225), 75e1051a39Sopenharmony_ci MODP(3072, 275), 76e1051a39Sopenharmony_ci MODP(4096, 325), 77e1051a39Sopenharmony_ci MODP(6144, 375), 78e1051a39Sopenharmony_ci MODP(8192, 400), 79e1051a39Sopenharmony_ci /* 80e1051a39Sopenharmony_ci * Additional dh named groups from RFC 5114 that have a different g. 81e1051a39Sopenharmony_ci * The uid can be any unique identifier. 82e1051a39Sopenharmony_ci */ 83e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 84e1051a39Sopenharmony_ci RFC5114("dh_1024_160", 1, 1024, 1024_160), 85e1051a39Sopenharmony_ci RFC5114("dh_2048_224", 2, 2048, 2048_224), 86e1051a39Sopenharmony_ci RFC5114("dh_2048_256", 3, 2048, 2048_256), 87e1051a39Sopenharmony_ci#endif 88e1051a39Sopenharmony_ci}; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ciconst DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name) 91e1051a39Sopenharmony_ci{ 92e1051a39Sopenharmony_ci size_t i; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { 95e1051a39Sopenharmony_ci if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0) 96e1051a39Sopenharmony_ci return &dh_named_groups[i]; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci return NULL; 99e1051a39Sopenharmony_ci} 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ciconst DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid) 102e1051a39Sopenharmony_ci{ 103e1051a39Sopenharmony_ci size_t i; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { 106e1051a39Sopenharmony_ci if (dh_named_groups[i].uid == uid) 107e1051a39Sopenharmony_ci return &dh_named_groups[i]; 108e1051a39Sopenharmony_ci } 109e1051a39Sopenharmony_ci return NULL; 110e1051a39Sopenharmony_ci} 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 113e1051a39Sopenharmony_ciconst DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p, 114e1051a39Sopenharmony_ci const BIGNUM *q, 115e1051a39Sopenharmony_ci const BIGNUM *g) 116e1051a39Sopenharmony_ci{ 117e1051a39Sopenharmony_ci size_t i; 118e1051a39Sopenharmony_ci 119e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { 120e1051a39Sopenharmony_ci /* Keep searching until a matching p and g is found */ 121e1051a39Sopenharmony_ci if (BN_cmp(p, dh_named_groups[i].p) == 0 122e1051a39Sopenharmony_ci && BN_cmp(g, dh_named_groups[i].g) == 0 123e1051a39Sopenharmony_ci /* Verify q is correct if it exists */ 124e1051a39Sopenharmony_ci && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0)) 125e1051a39Sopenharmony_ci return &dh_named_groups[i]; 126e1051a39Sopenharmony_ci } 127e1051a39Sopenharmony_ci return NULL; 128e1051a39Sopenharmony_ci} 129e1051a39Sopenharmony_ci#endif 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ciint ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) 132e1051a39Sopenharmony_ci{ 133e1051a39Sopenharmony_ci if (group == NULL) 134e1051a39Sopenharmony_ci return NID_undef; 135e1051a39Sopenharmony_ci return group->uid; 136e1051a39Sopenharmony_ci} 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ciconst char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group) 139e1051a39Sopenharmony_ci{ 140e1051a39Sopenharmony_ci if (group == NULL) 141e1051a39Sopenharmony_ci return NULL; 142e1051a39Sopenharmony_ci return group->name; 143e1051a39Sopenharmony_ci} 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 146e1051a39Sopenharmony_ciint ossl_ffc_named_group_get_keylength(const DH_NAMED_GROUP *group) 147e1051a39Sopenharmony_ci{ 148e1051a39Sopenharmony_ci if (group == NULL) 149e1051a39Sopenharmony_ci return 0; 150e1051a39Sopenharmony_ci return group->keylength; 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ciconst BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group) 154e1051a39Sopenharmony_ci{ 155e1051a39Sopenharmony_ci if (group == NULL) 156e1051a39Sopenharmony_ci return NULL; 157e1051a39Sopenharmony_ci return group->q; 158e1051a39Sopenharmony_ci} 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ciint ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) 161e1051a39Sopenharmony_ci{ 162e1051a39Sopenharmony_ci if (ffc == NULL || group == NULL) 163e1051a39Sopenharmony_ci return 0; 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, 166e1051a39Sopenharmony_ci (BIGNUM *)group->g); 167e1051a39Sopenharmony_ci ffc->keylength = group->keylength; 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci /* flush the cached nid, The DH layer is responsible for caching */ 170e1051a39Sopenharmony_ci ffc->nid = NID_undef; 171e1051a39Sopenharmony_ci return 1; 172e1051a39Sopenharmony_ci} 173e1051a39Sopenharmony_ci#endif 174