GNUnet  0.10.x
crypto_kdf.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
28 #include <gcrypt.h>
29 
30 #include "platform.h"
31 #include "gnunet_crypto_lib.h"
32 
33 #define LOG(kind, ...) GNUNET_log_from(kind, "util-crypto-kdf", __VA_ARGS__)
34 
46 int
48  size_t out_len,
49  const void *xts,
50  size_t xts_len,
51  const void *skm,
52  size_t skm_len,
53  va_list argp)
54 {
55  /*
56  * "Finally, we point out to a particularly advantageous instantiation using
57  * HMAC-SHA512 as XTR and HMAC-SHA256 in PRF* (in which case the output from SHA-512 is
58  * truncated to 256 bits). This makes sense in two ways: First, the extraction part is where we need a
59  * stronger hash function due to the unconventional demand from the hash function in the extraction
60  * setting. Second, as shown in Section 6, using HMAC with a truncated output as an extractor
61  * allows to prove the security of HKDF under considerably weaker assumptions on the underlying
62  * hash function."
63  *
64  * http://eprint.iacr.org/2010/264
65  */
66 
67  return GNUNET_CRYPTO_hkdf_v(result,
68  out_len,
69  GCRY_MD_SHA512,
70  GCRY_MD_SHA256,
71  xts,
72  xts_len,
73  skm,
74  skm_len,
75  argp);
76 }
77 
78 
90 int
92  size_t out_len,
93  const void *xts,
94  size_t xts_len,
95  const void *skm,
96  size_t skm_len, ...)
97 {
98  va_list argp;
99  int ret;
100 
101  va_start(argp, skm_len);
102  ret = GNUNET_CRYPTO_kdf_v(result,
103  out_len,
104  xts,
105  xts_len,
106  skm,
107  skm_len,
108  argp);
109  va_end(argp);
110 
111  return ret;
112 }
113 
114 
127 void
129  gcry_mpi_t n,
130  const void *xts, size_t xts_len,
131  const void *skm, size_t skm_len,
132  const char *ctx)
133 {
134  gcry_error_t rc;
135  unsigned int nbits;
136  size_t rsize;
137  unsigned int ctr;
138 
139  nbits = gcry_mpi_get_nbits(n);
140  /* GNUNET_assert (nbits > 512); */
141 
142  ctr = 0;
143  while (1)
144  {
145  /* Ain't clear if n is always divisible by 8 */
146  uint8_t buf[ (nbits - 1) / 8 + 1 ];
147 
148  rc = GNUNET_CRYPTO_kdf(buf,
149  sizeof(buf),
150  xts, xts_len,
151  skm, skm_len,
152  ctx, strlen(ctx),
153  &ctr, sizeof(ctr),
154  NULL, 0);
155  GNUNET_assert(GNUNET_YES == rc);
156 
157  rc = gcry_mpi_scan(r,
158  GCRYMPI_FMT_USG,
159  (const unsigned char *)buf,
160  sizeof(buf),
161  &rsize);
162  GNUNET_assert(0 == rc); /* Allocation erro? */
163 
164  gcry_mpi_clear_highbit(*r, nbits);
165  GNUNET_assert(0 == gcry_mpi_test_bit(*r, nbits));
166  ++ctr;
167  /* We reject this FDH if either *r > n and retry with another ctr */
168  if (0 > gcry_mpi_cmp(*r, n))
169  break;
170  gcry_mpi_release(*r);
171  }
172 }
173 
174 /* end of crypto_kdf.c */
int GNUNET_CRYPTO_hkdf_v(void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp)
Derive key.
Definition: crypto_hkdf.c:142
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
int GNUNET_CRYPTO_kdf_v(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp)
Derive key.
Definition: crypto_kdf.c:47
cryptographic primitives for GNUnet
void GNUNET_CRYPTO_kdf_mod_mpi(gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx)
Deterministically generate a pseudo-random number uniformly from the integers modulo a libgcrypt mpi...
Definition: crypto_kdf.c:128
static char buf[2048]
static int result
Global testing status.
#define GNUNET_YES
Definition: gnunet_common.h:77
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:91