19 #ifdef HAVE_RNG_RFC6979
26 #include "exceptions.h"
43 c = a[len] - b[len] - c;
45 c = c & 0xFFFFFF00 ? 1 : 0;
58 static size_t cx_rfc6979_bits2int(cx_rnd_rfc6979_ctx_t *rfc_ctx,
63 if (b_len > rfc_ctx->q_len) {
64 uint8_t right_shift = (b_len - rfc_ctx->q_len) & 7;
67 if (right_shift == 0) {
69 memmove(b_out, b, rfc_ctx->r_len >> 3);
74 size_t i, rlen = rfc_ctx->r_len >> 3;
76 for (i = 0; i < rlen; i++) {
78 b_out[i] = carry | (x >> right_shift);
79 carry = (x << (8 - right_shift)) & 0xff;
86 size_t padding_len = (rfc_ctx->r_len >> 3) - b_len;
87 memset(b_out, 0, padding_len);
88 memmove(b_out + padding_len, b, b_len);
90 return rfc_ctx->r_len;
102 static void cx_rfc6979_bits2octets(cx_rnd_rfc6979_ctx_t *rfc_ctx,
107 cx_rfc6979_bits2int(rfc_ctx, b, b_len, b_out);
108 if (memcmp(b_out, rfc_ctx->q, rfc_ctx->r_len >> 3) > 0) {
109 cx_rfc6979_sub(b_out, b_out, rfc_ctx->q, rfc_ctx->r_len >> 3);
120 static void cx_rfc6979_int2octets(cx_rnd_rfc6979_ctx_t *rfc_ctx,
126 delta = (i_len >> 3) - (rfc_ctx->r_len >> 3);
129 memcpy(b_out + delta, i, i_len >> 3);
136 memcpy(b_out, i + delta, rfc_ctx->r_len >> 3);
147 static uint32_t cx_rfc6979_bitslength(
const uint8_t *a,
size_t a_len)
161 while ((b & 0x80) == 0) {
168 static cx_err_t cx_rfc6979_hmacVK(cx_rnd_rfc6979_ctx_t *rfc_ctx,
180 len = rfc_ctx->md_len;
181 CX_CHECK(cx_hmac_init(&rfc_ctx->hmac, rfc_ctx->hash_id, rfc_ctx->k, rfc_ctx->md_len));
183 rfc_ctx->v[rfc_ctx->md_len] = opt;
186 CX_CHECK(cx_hmac_update(&rfc_ctx->hmac, rfc_ctx->v, len));
188 cx_rfc6979_int2octets(rfc_ctx, x, x_len * 8, rfc_ctx->tmp);
189 CX_CHECK(cx_hmac_update(&rfc_ctx->hmac, rfc_ctx->tmp, rfc_ctx->r_len >> 3));
192 cx_rfc6979_bits2octets(rfc_ctx, h1, h1_len * 8, rfc_ctx->tmp);
193 CX_CHECK(cx_hmac_update(&rfc_ctx->hmac, rfc_ctx->tmp, rfc_ctx->r_len >> 3));
200 len = rfc_ctx->md_len;
201 CX_CHECK(cx_hmac_final(&rfc_ctx->hmac, out, &len));
206 cx_err_t cx_rng_rfc6979_init(cx_rnd_rfc6979_ctx_t *rfc_ctx,
217 const cx_hash_info_t *hash_info = cx_hash_get_info(hash_id);
218 if (hash_info == NULL || hash_info->output_size == 0) {
219 return CX_INVALID_PARAMETER;
223 memcpy(rfc_ctx->q, q, q_len);
224 rfc_ctx->q_len = cx_rfc6979_bitslength(q, q_len);
225 rfc_ctx->r_len = (rfc_ctx->q_len + 7) & ~7;
226 rfc_ctx->hash_id = hash_id;
227 rfc_ctx->md_len = hash_info->output_size;
233 memset(rfc_ctx->v, 0x01, rfc_ctx->md_len);
236 memset(rfc_ctx->k, 0x00, rfc_ctx->md_len);
239 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx,
248 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx, -1, NULL, 0, NULL, 0, rfc_ctx->v));
251 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx,
260 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx, -1, NULL, 0, NULL, 0, rfc_ctx->v));
265 cx_err_t cx_rng_rfc6979_next(cx_rnd_rfc6979_ctx_t *rfc_ctx,
uint8_t *out,
size_t out_len)
270 cx_err_t error = CX_OK;
272 if ((out_len * 8) < rfc_ctx->r_len) {
273 return CX_INVALID_PARAMETER;
276 r_Blen = rfc_ctx->r_len >> 3;
286 while (t_Blen < r_Blen) {
287 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx, -1, NULL, 0, NULL, 0, rfc_ctx->v));
288 if (rfc_ctx->md_len > (r_Blen - t_Blen)) {
289 memcpy(out + t_Blen, rfc_ctx->v, r_Blen - t_Blen);
293 memcpy(out + t_Blen, rfc_ctx->v, rfc_ctx->md_len);
294 t_Blen += rfc_ctx->md_len;
299 cx_rfc6979_bits2int(rfc_ctx, out, t_Blen * 8, out);
300 if (memcmp(out, rfc_ctx->q, rfc_ctx->r_len >> 3) < 0) {
306 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx, 0, NULL, 0, NULL, 0, rfc_ctx->k));
308 CX_CHECK(cx_rfc6979_hmacVK(rfc_ctx, -1, NULL, 0, NULL, 0, rfc_ctx->v));
314 cx_err_t cx_rng_rfc6979(cx_md_t hash_id,
325 CX_CHECK(cx_rng_rfc6979_init(&
G_cx.rfc6979, hash_id, x, x_len, h1, h1_len, q, q_len));
326 CX_CHECK(cx_rng_rfc6979_next(&
G_cx.rfc6979, out, out_len));