GNUnet 0.26.2-44-g5a6b2f9a5
 
Loading...
Searching...
No Matches
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
48
51 size_t out_len,
52 const unsigned char *prk,
53 size_t prk_len,
54 size_t hkdf_args_len,
55 const struct GNUNET_CRYPTO_KdfInputArgument *hkdf_args)
56{
57 unsigned char *outbuf = (unsigned char*) result;
58 size_t i;
59 size_t ctx_len;
60
61 if (out_len > (0xff * crypto_auth_hmacsha256_BYTES))
62 return GNUNET_SYSERR;
63
64 ctx_len = 0;
65 for (i = 0; i < hkdf_args_len; i++)
66 {
67 size_t nxt = hkdf_args[i].data_length;
68 if (nxt + ctx_len < nxt)
69 {
70 /* integer overflow */
71 GNUNET_break (0);
72 return GNUNET_SYSERR;
73 }
74 ctx_len += nxt;
75 }
76
77 if ( (crypto_auth_hmacsha256_BYTES + ctx_len < ctx_len) ||
78 (crypto_auth_hmacsha256_BYTES + ctx_len + 1 < ctx_len) )
79 {
80 /* integer overflow */
81 GNUNET_break (0);
82 return GNUNET_SYSERR;
83 }
84
85 memset (result, 0, out_len);
86
87 {
88 size_t left = out_len;
89 unsigned char tmp[crypto_auth_hmacsha256_BYTES];
90 unsigned char ctx[ctx_len];
91 unsigned char *dst = ctx;
92 crypto_auth_hmacsha256_state st;
93 unsigned char counter = 1U;
94
95 sodium_memzero (ctx, sizeof ctx);
96 for (i = 0; i < hkdf_args_len; i++)
97 {
98 GNUNET_memcpy (dst, hkdf_args[i].data, hkdf_args[i].data_length);
99 dst += hkdf_args[i].data_length;
100 }
101
102 for (i = 0; left > 0; i += crypto_auth_hmacsha256_BYTES)
103 {
104 crypto_auth_hmacsha256_init (&st, prk, prk_len);
105 if (0 != i)
106 {
107 crypto_auth_hmacsha256_update (&st,
108 &outbuf[i - crypto_auth_hmacsha256_BYTES]
109 ,
110 crypto_auth_hmacsha256_BYTES);
111 }
112 crypto_auth_hmacsha256_update (&st, ctx, ctx_len);
113 crypto_auth_hmacsha256_update (&st, &counter, 1);
114 if (left >= crypto_auth_hmacsha256_BYTES)
115 {
116 crypto_auth_hmacsha256_final (&st, &outbuf[i]);
117 left -= crypto_auth_hmacsha256_BYTES;
118 }
119 else
120 {
121 crypto_auth_hmacsha256_final (&st, tmp);
122 memcpy (&outbuf[i], tmp, left);
123 sodium_memzero (tmp, sizeof tmp);
124 left = 0;
125 }
126 counter++;
127 }
128 sodium_memzero (&st, sizeof st);
129 }
130 return GNUNET_YES;
131}
132
133
136 size_t out_len,
137 const void *xts,
138 size_t xts_len,
139 const void *skm,
140 size_t skm_len,
141 size_t hkdf_args_len,
142 const struct
144 hkdf_args_len])
145{
146 unsigned char prk[crypto_auth_hmacsha512_BYTES];
147 crypto_auth_hmacsha512_state st;
148
149 memset (result, 0, out_len);
150 if (crypto_auth_hmacsha512_init (&st, xts, xts_len))
151 return GNUNET_SYSERR;
152 if (crypto_auth_hmacsha512_update (&st, skm, skm_len))
153 return GNUNET_SYSERR;
154 crypto_auth_hmacsha512_final (&st, (unsigned char*) prk);
155 sodium_memzero (&st, sizeof st);
156
157 return hkdf_expand_fixed (result, out_len,
158 prk,
159 sizeof prk,
160 hkdf_args_len,
161 hkdf_args);
162}
163
164
167 size_t out_len,
168 const struct GNUNET_ShortHashCode *prk,
169 size_t hkdf_args_len,
170 const struct
172 hkdf_args_len])
173{
174 return hkdf_expand_fixed (result, out_len,
175 (unsigned char*) prk, sizeof *prk,
176 hkdf_args_len,
177 hkdf_args);
178}
179
180
183 const void *xts,
184 size_t xts_len,
185 const void *skm,
186 size_t skm_len)
187{
188 crypto_auth_hmacsha256_state st;
189 if (crypto_auth_hmacsha256_init (&st, xts, xts_len))
190 return GNUNET_SYSERR;
191 if (crypto_auth_hmacsha256_update (&st, skm, skm_len))
192 return GNUNET_SYSERR;
193 crypto_auth_hmacsha256_final (&st, (unsigned char*) prk);
194 sodium_memzero (&st, sizeof st);
195 return GNUNET_OK;
196}
197
198
199/* end of crypto_hkdf.c */
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, size_t hkdf_args_len, const struct GNUNET_CRYPTO_KdfInputArgument hkdf_args[hkdf_args_len])
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand_v(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk, size_t hkdf_args_len, const struct GNUNET_CRYPTO_KdfInputArgument hkdf_args[hkdf_args_len])
static enum GNUNET_GenericReturnValue hkdf_expand_fixed(void *result, size_t out_len, const unsigned char *prk, size_t prk_len, size_t hkdf_args_len, const struct GNUNET_CRYPTO_KdfInputArgument *hkdf_args)
Definition crypto_hkdf.c:50
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static char * data
The data to insert into the dht.
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.
#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.
As input for variadic HKDF API.
A 256-bit hashcode.