GNUnet 0.22.2
crypto_hkdf.c
Go to the documentation of this file.
1/*
2 Copyright (c) 2010 Nils Durner
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22
39#include "sodium/utils.h"
40#include <stdio.h>
41#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-hkdf", __VA_ARGS__)
42
43#include "platform.h"
44#include "gnunet_common.h"
45#include "gnunet_util_lib.h"
46#include "sodium/crypto_auth_hmacsha256.h"
47
50 size_t out_len,
51 const unsigned char *prk,
52 size_t prk_len,
53 va_list argp)
54{
55 unsigned char *outbuf = (unsigned char*) result;
56 size_t i;
57 size_t ctx_len;
58 va_list args;
59
60 if (out_len > (0xff * crypto_auth_hmacsha256_BYTES))
61 return GNUNET_SYSERR;
62
63 va_copy (args, argp);
64
65 ctx_len = 0;
66 while (NULL != va_arg (args, void *))
67 {
68 size_t nxt = va_arg (args, size_t);
69 if (nxt + ctx_len < nxt)
70 {
71 /* integer overflow */
72 GNUNET_break (0);
73 va_end (args);
74 return GNUNET_SYSERR;
75 }
76 ctx_len += nxt;
77 }
78
79 va_end (args);
80
81 if ( (crypto_auth_hmacsha256_BYTES + ctx_len < ctx_len) ||
82 (crypto_auth_hmacsha256_BYTES + ctx_len + 1 < ctx_len) )
83 {
84 /* integer overflow */
85 GNUNET_break (0);
86 return GNUNET_SYSERR;
87 }
88
89 memset (result, 0, out_len);
90
91 {
92 size_t left = out_len;
93 const void *ctx_arg;
94 unsigned char tmp[crypto_auth_hmacsha256_BYTES];
95 unsigned char ctx[ctx_len];
96 unsigned char *dst = ctx;
97 crypto_auth_hmacsha256_state st;
98 unsigned char counter = 1U;
99
100 sodium_memzero (ctx, sizeof ctx);
101 va_copy (args, argp);
102 while ((ctx_arg = va_arg (args, void *)))
103 {
104 size_t len;
105
106 len = va_arg (args, size_t);
107 GNUNET_memcpy (dst, ctx_arg, len);
108 dst += len;
109 }
110 va_end (args);
111
112 for (i = 0; left > 0; i += crypto_auth_hmacsha256_BYTES)
113 {
114 crypto_auth_hmacsha256_init(&st, prk, prk_len);
115 if (0 != i)
116 {
117 crypto_auth_hmacsha256_update(&st,
118 &outbuf[i - crypto_auth_hmacsha256_BYTES],
119 crypto_auth_hmacsha256_BYTES);
120 }
121 crypto_auth_hmacsha256_update(&st, ctx, ctx_len);
122 crypto_auth_hmacsha256_update(&st, &counter, 1);
123 if (left >= crypto_auth_hmacsha256_BYTES)
124 {
125 crypto_auth_hmacsha256_final(&st, &outbuf[i]);
126 left -= crypto_auth_hmacsha256_BYTES;
127 }
128 else
129 {
130 crypto_auth_hmacsha256_final(&st, tmp);
131 memcpy (&outbuf[i], tmp, left);
132 sodium_memzero(tmp, sizeof tmp);
133 left = 0;
134 }
135 counter++;
136 }
137 sodium_memzero(&st, sizeof st);
138 }
139 return GNUNET_YES;
140}
141
142
145 size_t out_len,
146 const struct GNUNET_ShortHashCode *prk,
147 va_list argp)
148{
149 return hkdf_expand (result, out_len,
150 (unsigned char*) prk, sizeof *prk,
151 argp);
152}
153
154
157 size_t out_len,
158 const struct GNUNET_ShortHashCode *prk,
159 ...)
160{
161 va_list argp;
163
164 va_start (argp, prk);
165 ret = GNUNET_CRYPTO_hkdf_expand_v (result, out_len, prk, argp);
166 va_end (argp);
167 return ret;
168}
169
170
173 size_t out_len,
174 const void *xts,
175 size_t xts_len,
176 const void *skm,
177 size_t skm_len,
178 va_list argp)
179{
180 unsigned char prk[crypto_auth_hmacsha512_BYTES];
181 crypto_auth_hmacsha512_state st;
182
183 memset (result, 0, out_len);
184 if (crypto_auth_hmacsha512_init (&st, xts, xts_len))
185 return GNUNET_SYSERR;
186 if (crypto_auth_hmacsha512_update (&st, skm, skm_len))
187 return GNUNET_SYSERR;
188 crypto_auth_hmacsha512_final (&st, (unsigned char*) prk);
189 sodium_memzero (&st, sizeof st);
190
191 return hkdf_expand (result, out_len,
192 prk,
193 sizeof prk,
194 argp);
195}
196
197
200 size_t out_len,
201 const void *xts,
202 size_t xts_len,
203 const void *skm,
204 size_t skm_len, ...)
205{
206 va_list argp;
208
209 va_start (argp, skm_len);
210 ret =
212 out_len,
213 xts,
214 xts_len,
215 skm,
216 skm_len,
217 argp);
218 va_end (argp);
219 return ret;
220}
221
222
225 const void *xts,
226 size_t xts_len,
227 const void *skm,
228 size_t skm_len)
229{
230 crypto_auth_hmacsha256_state st;
231 if (crypto_auth_hmacsha256_init (&st, xts, xts_len))
232 return GNUNET_SYSERR;
233 if (crypto_auth_hmacsha256_update (&st, skm, skm_len))
234 return GNUNET_SYSERR;
235 crypto_auth_hmacsha256_final (&st, (unsigned char*) prk);
236 sodium_memzero (&st, sizeof st);
237 return GNUNET_OK;
238}
239
240
241/* end of crypto_hkdf.c */
static enum GNUNET_GenericReturnValue hkdf_expand(void *result, size_t out_len, const unsigned char *prk, size_t prk_len, va_list argp)
Definition: crypto_hkdf.c:49
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static struct GNUNET_FS_Handle * ctx
static int result
Global testing status.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *xts, size_t xts_len, const void *skm, size_t skm_len)
HKDF-Extract using SHA256.
Definition: crypto_hkdf.c:224
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_gnunet(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
Definition: crypto_hkdf.c:199
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_gnunet_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_hkdf.c:172
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
Definition: crypto_hkdf.c:156
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand_v(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk, va_list argp)
HKDF-Expand using SHA256.
Definition: crypto_hkdf.c:144
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
A 256-bit hashcode.