ASCON Suite
ascon-hkdf-common.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR 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
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * The contents of this header file expand out to the full implementation of
25  * HKDF for a specific underlying hash algorithm. We expect a number of
26  * macros to be defined before this file is included to configure the
27  * underlying HKDF variant:
28  *
29  * HKDF_ALG_NAME Name of the HKDF algorithm; e.g. ascon_hkdf
30  * HKDF_STATE Type for the HKDF state; e.g. ascon_khdf_state_t
31  * HKDF_HMAC_SIZE Size of the output for the HMAC algorithm.
32  * HKDF_HMAC_STATE Type for the HMAC state; e.g. ascon_hmac_state_t
33  * HKDF_HMAC_INIT Name of the HMAC initialization function.
34  * HKDF_HMAC_UPDATE Name of the HMAC update function.
35  * HKDF_HMAC_FINALIZE Name of the HMAC finalization function.
36  * HKDF_HMAC_FREE Name of the HMAC free function.
37  */
38 #if defined(HKDF_ALG_NAME)
39 
40 #define HKDF_CONCAT_INNER(name,suffix) name##suffix
41 #define HKDF_CONCAT(name,suffix) HKDF_CONCAT_INNER(name,suffix)
42 
43 int HKDF_ALG_NAME
44  (unsigned char *out, size_t outlen,
45  const unsigned char *key, size_t keylen,
46  const unsigned char *salt, size_t saltlen,
47  const unsigned char *info, size_t infolen)
48 {
50  if (outlen > (size_t)(HKDF_HMAC_SIZE * 255))
51  return -1;
52  HKDF_CONCAT(HKDF_ALG_NAME,_extract)(&state, key, keylen, salt, saltlen);
53  HKDF_CONCAT(HKDF_ALG_NAME,_expand)(&state, info, infolen, out, outlen);
54  ascon_clean(&state, sizeof(state));
55  return 0;
56 }
57 
58 void HKDF_CONCAT(HKDF_ALG_NAME,_extract)
59  (HKDF_STATE *state,
60  const unsigned char *key, size_t keylen,
61  const unsigned char *salt, size_t saltlen)
62 {
63  HKDF_HMAC_STATE hmac;
64  HKDF_HMAC_INIT(&hmac, salt, saltlen);
65  HKDF_HMAC_UPDATE(&hmac, key, keylen);
66  HKDF_HMAC_FINALIZE(&hmac, salt, saltlen, state->prk);
67  HKDF_HMAC_FREE(&hmac);
68  state->counter = 1;
69  state->posn = HKDF_HMAC_SIZE;
70 }
71 
72 int HKDF_CONCAT(HKDF_ALG_NAME,_expand)
73  (HKDF_STATE *state,
74  const unsigned char *info, size_t infolen,
75  unsigned char *out, size_t outlen)
76 {
77  HKDF_HMAC_STATE hmac;
78  size_t len;
79 
80  /* Deal with left-over data from the last output block */
81  len = HKDF_HMAC_SIZE - state->posn;
82  if (len > outlen)
83  len = outlen;
84  memcpy(out, state->out + state->posn, len);
85  out += len;
86  outlen -= len;
87  state->posn += len;
88 
89  /* Squeeze out the data one block at a time */
90  while (outlen > 0) {
91  /* Have we squeezed out too many blocks already? */
92  if (state->counter == 0) {
93  memset(out, 0, outlen); /* Zero the rest of the output data */
94  ascon_clean(&hmac, sizeof(hmac));
95  return -1;
96  }
97 
98  /* Squeeze out the next block of data */
99  HKDF_HMAC_INIT(&hmac, state->prk, sizeof(state->prk));
100  if (state->counter != 1)
101  HKDF_HMAC_UPDATE(&hmac, state->out, sizeof(state->out));
102  HKDF_HMAC_UPDATE(&hmac, info, infolen);
103  HKDF_HMAC_UPDATE(&hmac, &(state->counter), 1);
104  HKDF_HMAC_FINALIZE(&hmac, state->prk, sizeof(state->prk), state->out);
105  HKDF_HMAC_FREE(&hmac);
106  ++(state->counter);
107 
108  /* Copy the data to the output buffer */
109  len = HKDF_HMAC_SIZE;
110  if (len > outlen)
111  len = outlen;
112  memcpy(out, state->out, len);
113  state->posn = len;
114  out += len;
115  outlen -= len;
116  }
117  return 0;
118 }
119 
120 void HKDF_CONCAT(HKDF_ALG_NAME,_free)(HKDF_STATE *state)
121 {
122  ascon_clean(state, sizeof(HKDF_STATE));
123 }
124 
125 #endif /* HKDF_ALG_NAME */
126 
127 /* Now undefine everything so that we can include this file again for
128  * another variant on the HKDF algorithm */
129 #undef HKDF_ALG_NAME
130 #undef HKDF_STATE
131 #undef HKDF_HMAC_SIZE
132 #undef HKDF_HMAC_STATE
133 #undef HKDF_HMAC_INIT
134 #undef HKDF_HMAC_UPDATE
135 #undef HKDF_HMAC_FINALIZE
136 #undef HKDF_HMAC_FREE
#define HKDF_STATE
Definition: ascon-hkdf.c:33
#define HKDF_HMAC_UPDATE
Definition: ascon-hkdf.c:37
#define HKDF_HMAC_SIZE
Definition: ascon-hkdf.c:34
#define HKDF_ALG_NAME
Definition: ascon-hkdf.c:32
#define HKDF_HMAC_FREE
Definition: ascon-hkdf.c:39
#define HKDF_HMAC_FINALIZE
Definition: ascon-hkdf.c:38
#define HKDF_HMAC_STATE
Definition: ascon-hkdf.c:35
#define HKDF_HMAC_INIT
Definition: ascon-hkdf.c:36
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
void ascon_clean(void *buf, unsigned size)
Cleans a buffer that contains sensitive material.
Definition: ascon-clean.c:38