1 /* 2 * Copyright 2022-2024 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 <string.h> 11 #include <openssl/bn.h> 12 #include <openssl/evp.h> 13 #include <openssl/core_names.h> 14 #include <openssl/kdf.h> 15 #include "internal/deterministic_nonce.h" 16 #include "crypto/bn.h" 17 18 /* 19 * Convert a Bit String to an Integer (See RFC 6979 Section 2.3.2) 20 * 21 * Params: 22 * out The returned Integer as a BIGNUM 23 * qlen_bits The maximum size of the returned integer in bits. The returned 24 * Integer is shifted right if inlen is larger than qlen_bits.. 25 * in, inlen The input Bit String (in bytes). 26 * Returns: 1 if successful, or 0 otherwise. 27 */ 28 static int bits2int(BIGNUM *out, int qlen_bits, 29 const unsigned char *in, size_t inlen) 30 { 31 int blen_bits = inlen * 8; 32 int shift; 33 34 if (BN_bin2bn(in, (int)inlen, out) == NULL) 35 return 0; 36 37 shift = blen_bits - qlen_bits; 38 if (shift > 0) 39 return BN_rshift(out, out, shift); 40 return 1; 41 } 42 43 /* 44 * Convert as above a Bit String in const time to an Integer w fixed top 45 * 46 * Params: 47 * out The returned Integer as a BIGNUM 48 * qlen_bits The maximum size of the returned integer in bits. The returned 49 * Integer is shifted right if inlen is larger than qlen_bits.. 50 * in, inlen The input Bit String (in bytes). It has sizeof(BN_ULONG) bytes 51 * prefix with all bits set that needs to be cleared out after 52 * the conversion. 53 * Returns: 1 if successful, or 0 otherwise. 54 */ 55 static int bits2int_consttime(BIGNUM *out, int qlen_bits, 56 const unsigned char *in, size_t inlen) 57 { 58 int blen_bits = (inlen - sizeof(BN_ULONG)) * 8; 59 int shift; 60 61 if (BN_bin2bn(in, (int)inlen, out) == NULL) 62 return 0; 63 64 BN_set_flags(out, BN_FLG_CONSTTIME); 65 ossl_bn_mask_bits_fixed_top(out, blen_bits); 66 67 shift = blen_bits - qlen_bits; 68 if (shift > 0) 69 return bn_rshift_fixed_top(out, out, shift); 70 return 1; 71 } 72 73 /* 74 * Convert an Integer to an Octet String (See RFC 6979 2.3.3). 75 * The value is zero padded if required. 76 * 77 * Params: 78 * out The returned Octet String 79 * num The input Integer 80 * rlen The required size of the returned Octet String in bytes 81 * Returns: 1 if successful, or 0 otherwise. 82 */ 83 static int int2octets(unsigned char *out, const BIGNUM *num, int rlen) 84 { 85 return BN_bn2binpad(num, out, rlen) >= 0; 86 } 87 88 /* 89 * Convert a Bit String to an Octet String (See RFC 6979 Section 2.3.4) 90 * 91 * Params: 92 * out The returned octet string. 93 * q The modulus 94 * qlen_bits The length of q in bits 95 * rlen The value of qlen_bits rounded up to the nearest 8 bits. 96 * in, inlen The input bit string (in bytes) 97 * Returns: 1 if successful, or 0 otherwise. 98 */ 99 static int bits2octets(unsigned char *out, const BIGNUM *q, int qlen_bits, 100 int rlen, const unsigned char *in, size_t inlen) 101 { 102 int ret = 0; 103 BIGNUM *z = BN_new(); 104 105 if (z == NULL 106 || !bits2int(z, qlen_bits, in, inlen)) 107 goto err; 108 109 /* z2 = z1 mod q (Do a simple subtract, since z1 < 2^qlen_bits) */ 110 if (BN_cmp(z, q) >= 0 111 && !BN_usub(z, z, q)) 112 goto err; 113 114 ret = int2octets(out, z, rlen); 115 err: 116 BN_free(z); 117 return ret; 118 } 119 120 /* 121 * Setup a KDF HMAC_DRBG object using fixed entropy and nonce data. 122 * 123 * Params: 124 * digestname The digest name for the HMAC 125 * entropy, entropylen A fixed input entropy buffer 126 * nonce, noncelen A fixed input nonce buffer 127 * libctx, propq Are used for fetching algorithms 128 * 129 * Returns: The created KDF HMAC_DRBG object if successful, or NULL otherwise. 130 */ 131 static EVP_KDF_CTX *kdf_setup(const char *digestname, 132 const unsigned char *entropy, size_t entropylen, 133 const unsigned char *nonce, size_t noncelen, 134 OSSL_LIB_CTX *libctx, const char *propq) 135 { 136 EVP_KDF_CTX *ctx = NULL; 137 EVP_KDF *kdf = NULL; 138 OSSL_PARAM params[5], *p; 139 140 kdf = EVP_KDF_fetch(libctx, "HMAC-DRBG-KDF", propq); 141 ctx = EVP_KDF_CTX_new(kdf); 142 EVP_KDF_free(kdf); 143 if (ctx == NULL) 144 goto err; 145 146 p = params; 147 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, 148 (char *)digestname, 0); 149 if (propq != NULL) 150 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, 151 (char *)propq, 0); 152 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_HMACDRBG_ENTROPY, 153 (void *)entropy, entropylen); 154 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_HMACDRBG_NONCE, 155 (void *)nonce, noncelen); 156 *p = OSSL_PARAM_construct_end(); 157 158 if (EVP_KDF_CTX_set_params(ctx, params) <= 0) 159 goto err; 160 161 return ctx; 162 err: 163 EVP_KDF_CTX_free(ctx); 164 return NULL; 165 } 166 167 /* 168 * Generate a Deterministic nonce 'k' for DSA/ECDSA as defined in 169 * RFC 6979 Section 3.3. "Alternate Description of the Generation of k" 170 * 171 * Params: 172 * out Returns the generated deterministic nonce 'k' 173 * q A large prime number used for modulus operations for DSA and ECDSA. 174 * priv The private key in the range [1, q-1] 175 * hm, hmlen The digested message buffer in bytes 176 * digestname The digest name used for signing. It is used as the HMAC digest. 177 * libctx, propq Used for fetching algorithms 178 * 179 * Returns: 1 if successful, or 0 otherwise. 180 */ 181 int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, 182 const BIGNUM *priv, 183 const unsigned char *hm, size_t hmlen, 184 const char *digestname, 185 OSSL_LIB_CTX *libctx, 186 const char *propq) 187 { 188 EVP_KDF_CTX *kdfctx = NULL; 189 int ret = 0, rlen = 0, qlen_bits = 0; 190 unsigned char *entropyx = NULL, *nonceh = NULL, *rbits = NULL, *T = NULL; 191 size_t allocsz = 0; 192 const size_t prefsz = sizeof(BN_ULONG); 193 194 if (out == NULL) 195 return 0; 196 197 qlen_bits = BN_num_bits(q); 198 if (qlen_bits == 0) 199 return 0; 200 201 /* Note rlen used here is in bytes since the input values are byte arrays */ 202 rlen = (qlen_bits + 7) / 8; 203 allocsz = prefsz + 3 * rlen; 204 205 /* Use a single alloc for the buffers T, nonceh and entropyx */ 206 T = (unsigned char *)OPENSSL_zalloc(allocsz); 207 if (T == NULL) 208 return 0; 209 rbits = T + prefsz; 210 nonceh = rbits + rlen; 211 entropyx = nonceh + rlen; 212 213 memset(T, 0xff, prefsz); 214 215 if (!int2octets(entropyx, priv, rlen) 216 || !bits2octets(nonceh, q, qlen_bits, rlen, hm, hmlen)) 217 goto end; 218 219 kdfctx = kdf_setup(digestname, entropyx, rlen, nonceh, rlen, libctx, propq); 220 if (kdfctx == NULL) 221 goto end; 222 223 do { 224 if (!EVP_KDF_derive(kdfctx, rbits, rlen, NULL) 225 || !bits2int_consttime(out, qlen_bits, T, rlen + prefsz)) 226 goto end; 227 } while (ossl_bn_is_word_fixed_top(out, 0) 228 || ossl_bn_is_word_fixed_top(out, 1) 229 || BN_ucmp(out, q) >= 0); 230 #ifdef BN_DEBUG 231 /* With BN_DEBUG on a fixed top number cannot be returned */ 232 bn_correct_top(out); 233 #endif 234 ret = 1; 235 236 end: 237 EVP_KDF_CTX_free(kdfctx); 238 OPENSSL_clear_free(T, allocsz); 239 return ret; 240 } 241