kmac_xof.c
Go to the documentation of this file.
1 /**
2  * @file kmac_xof.c
3  * @brief KMACXOF (KMAC with arbitrary-length output)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * @author Oryx Embedded SARL (www.oryx-embedded.com)
24  * @version 2.6.6
25  **/
26 
27 //Switch to the appropriate trace level
28 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
29 
30 //Dependencies
31 #include "core/crypto.h"
32 #include "xof/kmac_xof.h"
33 
34 //Check crypto library configuration
35 #if (KMAC_XOF_SUPPORT == ENABLED)
36 
37 //KMACXOF128 object identifier (2.16.840.1.101.3.4.2.21)
38 const uint8_t KMAC_XOF128_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x15};
39 //KMACXOF256 object identifier (2.16.840.1.101.3.4.2.22)
40 const uint8_t KMAC_XOF256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x16};
41 
42 
43 /**
44  * @brief Digest a message using KMACXOF
45  * @param[in] strength Number of bits of security (128 for KMACXOF128 and
46  * 256 for KMACXOF256)
47  * @param[in] key Pointer to the secret key (K)
48  * @param[in] keyLen Length of the secret key
49  * @param[in] input Pointer to the input data (X)
50  * @param[in] inputLen Length of the input data
51  * @param[in] custom Customization string (S)
52  * @param[in] customLen Length of the customization string
53  * @param[out] output Pointer to the output data
54  * @param[in] outputLen Expected length of the output data (L)
55  * @return Error code
56  **/
57 
58 error_t kmacXofCompute(uint_t strength, const void *key, size_t keyLen,
59  const void *input, size_t inputLen, const char_t *custom, size_t customLen,
60  uint8_t *output, size_t outputLen)
61 {
62  error_t error;
63 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
64  KmacXofContext *context;
65 #else
66  KmacXofContext context[1];
67 #endif
68 
69  //Check parameters
70  if(input == NULL && inputLen != 0)
72 
73  if(output == NULL && outputLen != 0)
75 
76 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
77  //Allocate a memory buffer to hold the KMACXOF context
78  context = cryptoAllocMem(sizeof(KmacXofContext));
79  //Failed to allocate memory?
80  if(context == NULL)
81  return ERROR_OUT_OF_MEMORY;
82 #endif
83 
84  //Initialize the KMACXOF context
85  error = kmacXofInit(context, strength, key, keyLen, custom, customLen);
86 
87  //Check status code
88  if(!error)
89  {
90  //Absorb input data
91  kmacXofAbsorb(context, input, inputLen);
92  //Finish absorbing phase
93  kmacXofFinal(context);
94  //Extract data from the squeezing phase
95  kmacXofSqueeze(context, output, outputLen);
96  }
97 
98 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
99  //Free previously allocated memory
100  cryptoFreeMem(context);
101 #endif
102 
103  //Return status code
104  return error;
105 }
106 
107 
108 /**
109  * @brief Initialize KMACXOF context
110  * @param[in] context Pointer to the KMACXOF context to initialize
111  * @param[in] strength Number of bits of security (128 for KMACXOF128 and
112  * 256 for KMACXOF256)
113  * @param[in] key Pointer to the secret key (K)
114  * @param[in] keyLen Length of the secret key
115  * @param[in] custom Customization string (S)
116  * @param[in] customLen Length of the customization string
117  * @return Error code
118  **/
119 
120 error_t kmacXofInit(KmacXofContext *context, uint_t strength, const void *key,
121  size_t keyLen, const char_t *custom, size_t customLen)
122 {
123  error_t error;
124  size_t i;
125  size_t n;
126  size_t rate;
127  uint8_t buffer[sizeof(size_t) + 1];
128 
129  //Make sure the KMACXOF context is valid
130  if(context == NULL)
132 
133  //Make sure the supplied key is valid
134  if(key == NULL && keyLen != 0)
136 
137  //Initialize cSHAKE context
138  error = cshakeInit(&context->cshakeContext, strength, "KMAC", 4, custom,
139  customLen);
140  //Any error to report?
141  if(error)
142  return error;
143 
144  //The rate of the underlying Keccak sponge function is 168 for KMACXOF128
145  //and 136 for KMACXOF256
146  rate = context->cshakeContext.keccakContext.blockSize;
147 
148  //Absorb the string representation of the rate
149  cshakeLeftEncode(rate, buffer, &n);
150  cshakeAbsorb(&context->cshakeContext, buffer, n);
151  i = n;
152 
153  //Absorb the string representation of K
154  cshakeLeftEncode(keyLen * 8, buffer, &n);
155  cshakeAbsorb(&context->cshakeContext, buffer, n);
156  cshakeAbsorb(&context->cshakeContext, key, keyLen);
157  i += n + keyLen;
158 
159  //The padding string consists of bytes set to zero
160  buffer[0] = 0;
161 
162  //Pad the result with zeros until it is a byte string whose length in
163  //bytes is a multiple of the rate
164  while((i % rate) != 0)
165  {
166  //Absorb the padding string
167  cshakeAbsorb(&context->cshakeContext, buffer, 1);
168  i++;
169  }
170 
171  //Successful initialization
172  return NO_ERROR;
173 }
174 
175 
176 /**
177  * @brief Absorb data
178  * @param[in] context Pointer to the KMACXOF context
179  * @param[in] input Pointer to the buffer being hashed
180  * @param[in] length Length of the buffer
181  **/
182 
183 void kmacXofAbsorb(KmacXofContext *context, const void *input, size_t length)
184 {
185  //Absorb the input data
186  cshakeAbsorb(&context->cshakeContext, input, length);
187 }
188 
189 
190 /**
191  * @brief Finish absorbing phase
192  * @param[in] context Pointer to the KMACXOF context
193  **/
194 
196 {
197  uint8_t buffer[2];
198 
199  //When used as a XOF, KMAC is computed by setting the encoded output length
200  //to 0
201  buffer[0] = 0;
202  buffer[1] = 1;
203  cshakeAbsorb(&context->cshakeContext, buffer, 2);
204 
205  //Finish absorbing phase
206  cshakeFinal(&context->cshakeContext);
207 }
208 
209 
210 /**
211  * @brief Extract data from the squeezing phase
212  * @param[in] context Pointer to the KMACXOF context
213  * @param[out] output Output string
214  * @param[in] length Desired output length, in bytes
215  **/
216 
217 void kmacXofSqueeze(KmacXofContext *context, uint8_t *output, size_t length)
218 {
219  //Extract data from the squeezing phase
220  cshakeSqueeze(&context->cshakeContext, output, length);
221 }
222 
223 #endif
error_t cshakeInit(CshakeContext *context, uint_t strength, const char_t *name, size_t nameLen, const char_t *custom, size_t customLen)
Initialize cSHAKE context.
Definition: cshake.c:124
const uint8_t KMAC_XOF128_OID[9]
Definition: kmac_xof.c:38
KeccakContext keccakContext
Definition: cshake.h:52
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
const uint8_t KMAC_XOF256_OID[9]
Definition: kmac_xof.c:40
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
void cshakeFinal(CshakeContext *context)
Finish absorbing phase.
Definition: cshake.c:220
void kmacXofFinal(KmacXofContext *context)
Finish absorbing phase.
Definition: kmac_xof.c:195
error_t kmacXofInit(KmacXofContext *context, uint_t strength, const void *key, size_t keyLen, const char_t *custom, size_t customLen)
Initialize KMACXOF context.
Definition: kmac_xof.c:120
General definitions for cryptographic algorithms.
uint8_t length
Definition: tcp.h:375
KMACXOF (KMAC with arbitrary-length output)
void cshakeAbsorb(CshakeContext *context, const void *input, size_t length)
Absorb data.
Definition: cshake.c:208
void cshakeLeftEncode(size_t value, uint8_t *buffer, size_t *length)
Encode integer as byte string.
Definition: cshake.c:262
char char_t
Definition: compiler_port.h:55
uint8_t n
uint_t blockSize
Definition: keccak.h:119
#define cryptoFreeMem(p)
Definition: crypto.h:966
error_t kmacXofCompute(uint_t strength, const void *key, size_t keyLen, const void *input, size_t inputLen, const char_t *custom, size_t customLen, uint8_t *output, size_t outputLen)
Digest a message using KMACXOF.
Definition: kmac_xof.c:58
#define cryptoAllocMem(size)
Definition: crypto.h:961
void kmacXofAbsorb(KmacXofContext *context, const void *input, size_t length)
Absorb data.
Definition: kmac_xof.c:183
KMACXOF algorithm context.
Definition: kmac_xof.h:49
unsigned int uint_t
Definition: compiler_port.h:57
CshakeContext cshakeContext
Definition: kmac_xof.h:50
@ NO_ERROR
Success.
Definition: error.h:44
void kmacXofSqueeze(KmacXofContext *context, uint8_t *output, size_t length)
Extract data from the squeezing phase.
Definition: kmac_xof.c:217
void cshakeSqueeze(CshakeContext *context, uint8_t *output, size_t length)
Extract data from the squeezing phase.
Definition: cshake.c:248