1 1.1 christos /* 2 1.1 christos * Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos /* 11 1.1 christos * See SP800-185 "Appendix A - KMAC, .... in Terms of Keccak[c]" 12 1.1 christos * 13 1.1 christos * Inputs are: 14 1.1 christos * K = Key (len(K) < 2^2040 bits) 15 1.1 christos * X = Input 16 1.1 christos * L = Output length (0 <= L < 2^2040 bits) 17 1.1 christos * S = Customization String Default="" (len(S) < 2^2040 bits) 18 1.1 christos * 19 1.1 christos * KMAC128(K, X, L, S) 20 1.1 christos * { 21 1.1 christos * newX = bytepad(encode_string(K), 168) || X || right_encode(L). 22 1.1 christos * T = bytepad(encode_string("KMAC") || encode_string(S), 168). 23 1.1 christos * return KECCAK[256](T || newX || 00, L). 24 1.1 christos * } 25 1.1 christos * 26 1.1 christos * KMAC256(K, X, L, S) 27 1.1 christos * { 28 1.1 christos * newX = bytepad(encode_string(K), 136) || X || right_encode(L). 29 1.1 christos * T = bytepad(encode_string("KMAC") || encode_string(S), 136). 30 1.1 christos * return KECCAK[512](T || newX || 00, L). 31 1.1 christos * } 32 1.1 christos * 33 1.1 christos * KMAC128XOF(K, X, L, S) 34 1.1 christos * { 35 1.1 christos * newX = bytepad(encode_string(K), 168) || X || right_encode(0). 36 1.1 christos * T = bytepad(encode_string("KMAC") || encode_string(S), 168). 37 1.1 christos * return KECCAK[256](T || newX || 00, L). 38 1.1 christos * } 39 1.1 christos * 40 1.1 christos * KMAC256XOF(K, X, L, S) 41 1.1 christos * { 42 1.1 christos * newX = bytepad(encode_string(K), 136) || X || right_encode(0). 43 1.1 christos * T = bytepad(encode_string("KMAC") || encode_string(S), 136). 44 1.1 christos * return KECCAK[512](T || newX || 00, L). 45 1.1 christos * } 46 1.1 christos * 47 1.1 christos */ 48 1.1 christos 49 1.1 christos #include <stdlib.h> 50 1.1 christos #include <string.h> 51 1.1 christos #include <openssl/core_dispatch.h> 52 1.1 christos #include <openssl/core_names.h> 53 1.1 christos #include <openssl/params.h> 54 1.1 christos #include <openssl/evp.h> 55 1.1 christos #include <openssl/err.h> 56 1.1 christos #include <openssl/proverr.h> 57 1.1 christos #include <openssl/fips_names.h> 58 1.1 christos #include "prov/securitycheck.h" 59 1.1 christos #include "prov/implementations.h" 60 1.1 christos #include "prov/provider_ctx.h" 61 1.1 christos #include "prov/provider_util.h" 62 1.1 christos #include "prov/providercommon.h" 63 1.1 christos #include "internal/cryptlib.h" /* ossl_assert */ 64 1.1 christos 65 1.1 christos /* 66 1.1 christos * Forward declaration of everything implemented here. This is not strictly 67 1.1 christos * necessary for the compiler, but provides an assurance that the signatures 68 1.1 christos * of the functions in the dispatch table are correct. 69 1.1 christos */ 70 1.1 christos static OSSL_FUNC_mac_newctx_fn kmac128_new; 71 1.1 christos static OSSL_FUNC_mac_newctx_fn kmac256_new; 72 1.1 christos static OSSL_FUNC_mac_dupctx_fn kmac_dup; 73 1.1 christos static OSSL_FUNC_mac_freectx_fn kmac_free; 74 1.1 christos static OSSL_FUNC_mac_gettable_ctx_params_fn kmac_gettable_ctx_params; 75 1.1 christos static OSSL_FUNC_mac_get_ctx_params_fn kmac_get_ctx_params; 76 1.1 christos static OSSL_FUNC_mac_settable_ctx_params_fn kmac_settable_ctx_params; 77 1.1 christos static OSSL_FUNC_mac_set_ctx_params_fn kmac_set_ctx_params; 78 1.1 christos static OSSL_FUNC_mac_init_fn kmac_init; 79 1.1 christos static OSSL_FUNC_mac_update_fn kmac_update; 80 1.1 christos static OSSL_FUNC_mac_final_fn kmac_final; 81 1.1 christos 82 1.1 christos #define KMAC_MAX_BLOCKSIZE ((1600 - 128 * 2) / 8) /* 168 */ 83 1.1 christos 84 1.1 christos /* 85 1.1 christos * Length encoding will be a 1 byte size + length in bits (3 bytes max) 86 1.1 christos * This gives a range of 0..0XFFFFFF bits = 2097151 bytes). 87 1.1 christos */ 88 1.1 christos #define KMAC_MAX_OUTPUT_LEN (0xFFFFFF / 8) 89 1.1 christos #define KMAC_MAX_ENCODED_HEADER_LEN (1 + 3) 90 1.1 christos 91 1.1 christos /* 92 1.1 christos * Restrict the maximum length of the customisation string. This must not 93 1.1 christos * exceed 64 bits = 8k bytes. 94 1.1 christos */ 95 1.1 christos #define KMAC_MAX_CUSTOM 512 96 1.1 christos 97 1.1 christos /* Maximum size of encoded custom string */ 98 1.1 christos #define KMAC_MAX_CUSTOM_ENCODED (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_HEADER_LEN) 99 1.1 christos 100 1.1 christos /* Maximum key size in bytes = 512 (4096 bits) */ 101 1.1 christos #define KMAC_MAX_KEY 512 102 1.1 christos #define KMAC_MIN_KEY 4 103 1.1 christos 104 1.1 christos /* 105 1.1 christos * Maximum Encoded Key size will be padded to a multiple of the blocksize 106 1.1 christos * i.e KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN = 512 + 4 107 1.1 christos * Padded to a multiple of KMAC_MAX_BLOCKSIZE 108 1.1 christos */ 109 1.1 christos #define KMAC_MAX_KEY_ENCODED (KMAC_MAX_BLOCKSIZE * 4) 110 1.1 christos 111 1.1 christos /* Fixed value of encode_string("KMAC") */ 112 1.1 christos static const unsigned char kmac_string[] = { 113 1.1 christos 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 114 1.1 christos }; 115 1.1 christos 116 1.1.1.2 christos #define KMAC_FLAG_XOF_MODE 1 117 1.1 christos 118 1.1 christos struct kmac_data_st { 119 1.1.1.2 christos void *provctx; 120 1.1 christos EVP_MD_CTX *ctx; 121 1.1 christos PROV_DIGEST digest; 122 1.1 christos size_t out_len; 123 1.1 christos size_t key_len; 124 1.1 christos size_t custom_len; 125 1.1 christos /* If xof_mode = 1 then we use right_encode(0) */ 126 1.1 christos int xof_mode; 127 1.1 christos /* key and custom are stored in encoded form */ 128 1.1 christos unsigned char key[KMAC_MAX_KEY_ENCODED]; 129 1.1 christos unsigned char custom[KMAC_MAX_CUSTOM_ENCODED]; 130 1.1 christos #ifdef FIPS_MODULE 131 1.1 christos /* 132 1.1 christos * 'internal' is set to 1 if KMAC is used inside another algorithm such as a 133 1.1 christos * KDF. In this case it is the parent algorithm that is responsible for 134 1.1 christos * performing any conditional FIPS indicator related checks for KMAC. 135 1.1 christos */ 136 1.1 christos int internal; 137 1.1 christos #endif 138 1.1 christos OSSL_FIPS_IND_DECLARE 139 1.1 christos }; 140 1.1 christos 141 1.1 christos static int encode_string(unsigned char *out, size_t out_max_len, size_t *out_len, 142 1.1.1.2 christos const unsigned char *in, size_t in_len); 143 1.1 christos static int right_encode(unsigned char *out, size_t out_max_len, size_t *out_len, 144 1.1.1.2 christos size_t bits); 145 1.1 christos static int bytepad(unsigned char *out, size_t *out_len, 146 1.1.1.2 christos const unsigned char *in1, size_t in1_len, 147 1.1.1.2 christos const unsigned char *in2, size_t in2_len, 148 1.1.1.2 christos size_t w); 149 1.1 christos static int kmac_bytepad_encode_key(unsigned char *out, size_t out_max_len, 150 1.1.1.2 christos size_t *out_len, 151 1.1.1.2 christos const unsigned char *in, size_t in_len, 152 1.1.1.2 christos size_t w); 153 1.1 christos 154 1.1 christos static void kmac_free(void *vmacctx) 155 1.1 christos { 156 1.1 christos struct kmac_data_st *kctx = vmacctx; 157 1.1 christos 158 1.1 christos if (kctx != NULL) { 159 1.1 christos EVP_MD_CTX_free(kctx->ctx); 160 1.1 christos ossl_prov_digest_reset(&kctx->digest); 161 1.1 christos OPENSSL_cleanse(kctx->key, kctx->key_len); 162 1.1 christos OPENSSL_cleanse(kctx->custom, kctx->custom_len); 163 1.1 christos OPENSSL_free(kctx); 164 1.1 christos } 165 1.1 christos } 166 1.1 christos 167 1.1 christos /* 168 1.1 christos * We have KMAC implemented as a hash, which we can use instead of 169 1.1 christos * reimplementing the EVP functionality with direct use of 170 1.1 christos * keccak_mac_init() and friends. 171 1.1 christos */ 172 1.1 christos static struct kmac_data_st *kmac_new(void *provctx) 173 1.1 christos { 174 1.1 christos struct kmac_data_st *kctx; 175 1.1 christos 176 1.1 christos if (!ossl_prov_is_running()) 177 1.1 christos return NULL; 178 1.1 christos 179 1.1 christos if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL 180 1.1.1.2 christos || (kctx->ctx = EVP_MD_CTX_new()) == NULL) { 181 1.1 christos kmac_free(kctx); 182 1.1 christos return NULL; 183 1.1 christos } 184 1.1 christos kctx->provctx = provctx; 185 1.1 christos OSSL_FIPS_IND_INIT(kctx) 186 1.1 christos return kctx; 187 1.1 christos } 188 1.1 christos 189 1.1 christos static void *kmac_fetch_new(void *provctx, const OSSL_PARAM *params) 190 1.1 christos { 191 1.1 christos struct kmac_data_st *kctx = kmac_new(provctx); 192 1.1 christos int md_size; 193 1.1 christos 194 1.1 christos if (kctx == NULL) 195 1.1 christos return 0; 196 1.1 christos if (!ossl_prov_digest_load_from_params(&kctx->digest, params, 197 1.1.1.2 christos PROV_LIBCTX_OF(provctx))) { 198 1.1 christos kmac_free(kctx); 199 1.1 christos return 0; 200 1.1 christos } 201 1.1 christos 202 1.1 christos md_size = EVP_MD_get_size(ossl_prov_digest_md(&kctx->digest)); 203 1.1 christos if (md_size <= 0) { 204 1.1 christos kmac_free(kctx); 205 1.1 christos return 0; 206 1.1 christos } 207 1.1 christos kctx->out_len = (size_t)md_size; 208 1.1 christos return kctx; 209 1.1 christos } 210 1.1 christos 211 1.1 christos static void *kmac128_new(void *provctx) 212 1.1 christos { 213 1.1 christos static const OSSL_PARAM kmac128_params[] = { 214 1.1 christos OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC128, 215 1.1.1.2 christos sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC128)), 216 1.1 christos OSSL_PARAM_END 217 1.1 christos }; 218 1.1 christos return kmac_fetch_new(provctx, kmac128_params); 219 1.1 christos } 220 1.1 christos 221 1.1 christos static void *kmac256_new(void *provctx) 222 1.1 christos { 223 1.1 christos static const OSSL_PARAM kmac256_params[] = { 224 1.1 christos OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC256, 225 1.1.1.2 christos sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC256)), 226 1.1 christos OSSL_PARAM_END 227 1.1 christos }; 228 1.1 christos return kmac_fetch_new(provctx, kmac256_params); 229 1.1 christos } 230 1.1 christos 231 1.1 christos static void *kmac_dup(void *vsrc) 232 1.1 christos { 233 1.1 christos struct kmac_data_st *src = vsrc; 234 1.1 christos struct kmac_data_st *dst; 235 1.1 christos 236 1.1 christos if (!ossl_prov_is_running()) 237 1.1 christos return NULL; 238 1.1 christos 239 1.1 christos dst = kmac_new(src->provctx); 240 1.1 christos if (dst == NULL) 241 1.1 christos return NULL; 242 1.1 christos 243 1.1 christos if (!EVP_MD_CTX_copy(dst->ctx, src->ctx) 244 1.1 christos || !ossl_prov_digest_copy(&dst->digest, &src->digest)) { 245 1.1 christos kmac_free(dst); 246 1.1 christos return NULL; 247 1.1 christos } 248 1.1 christos #ifdef FIPS_MODULE 249 1.1 christos dst->internal = src->internal; 250 1.1 christos #endif 251 1.1 christos dst->out_len = src->out_len; 252 1.1 christos dst->key_len = src->key_len; 253 1.1 christos dst->custom_len = src->custom_len; 254 1.1 christos dst->xof_mode = src->xof_mode; 255 1.1 christos memcpy(dst->key, src->key, src->key_len); 256 1.1 christos memcpy(dst->custom, src->custom, dst->custom_len); 257 1.1 christos OSSL_FIPS_IND_COPY(dst, src) 258 1.1 christos 259 1.1 christos return dst; 260 1.1 christos } 261 1.1 christos 262 1.1 christos static int kmac_setkey(struct kmac_data_st *kctx, const unsigned char *key, 263 1.1.1.2 christos size_t keylen) 264 1.1 christos { 265 1.1 christos const EVP_MD *digest = ossl_prov_digest_md(&kctx->digest); 266 1.1 christos int w = EVP_MD_get_block_size(digest); 267 1.1 christos 268 1.1 christos if (keylen < KMAC_MIN_KEY || keylen > KMAC_MAX_KEY) { 269 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 270 1.1 christos return 0; 271 1.1 christos } 272 1.1 christos #ifdef FIPS_MODULE 273 1.1 christos /* 274 1.1 christos * Only do the key check if KMAC is fetched directly. 275 1.1 christos * Other algorithms that embed KMAC such as SSKDF will ignore this check. 276 1.1 christos */ 277 1.1 christos if (!kctx->internal) { 278 1.1 christos int approved = ossl_mac_check_key_size(keylen); 279 1.1 christos 280 1.1 christos if (!approved) { 281 1.1 christos if (!OSSL_FIPS_IND_ON_UNAPPROVED(kctx, OSSL_FIPS_IND_SETTABLE1, 282 1.1.1.2 christos PROV_LIBCTX_OF(kctx->provctx), 283 1.1.1.2 christos "KMAC", "Key size", 284 1.1.1.2 christos ossl_fips_config_kmac_key_check)) { 285 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 286 1.1 christos return 0; 287 1.1 christos } 288 1.1 christos } 289 1.1 christos } 290 1.1 christos #endif 291 1.1 christos if (w <= 0) { 292 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 293 1.1 christos return 0; 294 1.1 christos } 295 1.1 christos if (!kmac_bytepad_encode_key(kctx->key, sizeof(kctx->key), &kctx->key_len, 296 1.1.1.2 christos key, keylen, (size_t)w)) 297 1.1 christos return 0; 298 1.1 christos return 1; 299 1.1 christos } 300 1.1 christos 301 1.1 christos /* 302 1.1 christos * The init() assumes that any ctrl methods are set beforehand for 303 1.1 christos * md, key and custom. Setting the fields afterwards will have no 304 1.1 christos * effect on the output mac. 305 1.1 christos */ 306 1.1 christos static int kmac_init(void *vmacctx, const unsigned char *key, 307 1.1.1.2 christos size_t keylen, const OSSL_PARAM params[]) 308 1.1 christos { 309 1.1 christos struct kmac_data_st *kctx = vmacctx; 310 1.1 christos EVP_MD_CTX *ctx = kctx->ctx; 311 1.1 christos unsigned char *out; 312 1.1 christos size_t out_len, block_len; 313 1.1 christos int res, t; 314 1.1 christos 315 1.1 christos if (!ossl_prov_is_running() || !kmac_set_ctx_params(kctx, params)) 316 1.1 christos return 0; 317 1.1 christos 318 1.1 christos if (key != NULL) { 319 1.1 christos if (!kmac_setkey(kctx, key, keylen)) 320 1.1 christos return 0; 321 1.1 christos } else if (kctx->key_len == 0) { 322 1.1 christos /* Check key has been set */ 323 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 324 1.1 christos return 0; 325 1.1 christos } 326 1.1 christos if (!EVP_DigestInit_ex(kctx->ctx, ossl_prov_digest_md(&kctx->digest), 327 1.1.1.2 christos NULL)) 328 1.1 christos return 0; 329 1.1 christos 330 1.1 christos t = EVP_MD_get_block_size(ossl_prov_digest_md(&kctx->digest)); 331 1.1 christos if (t <= 0) { 332 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 333 1.1 christos return 0; 334 1.1 christos } 335 1.1 christos block_len = t; 336 1.1 christos 337 1.1 christos /* Set default custom string if it is not already set */ 338 1.1 christos if (kctx->custom_len == 0) { 339 1.1 christos const OSSL_PARAM cparams[] = { 340 1.1 christos OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, "", 0), 341 1.1 christos OSSL_PARAM_END 342 1.1 christos }; 343 1.1 christos (void)kmac_set_ctx_params(kctx, cparams); 344 1.1 christos } 345 1.1 christos 346 1.1 christos if (!bytepad(NULL, &out_len, kmac_string, sizeof(kmac_string), 347 1.1.1.2 christos kctx->custom, kctx->custom_len, block_len)) { 348 1.1 christos ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 349 1.1 christos return 0; 350 1.1 christos } 351 1.1 christos out = OPENSSL_malloc(out_len); 352 1.1 christos if (out == NULL) 353 1.1 christos return 0; 354 1.1 christos res = bytepad(out, NULL, kmac_string, sizeof(kmac_string), 355 1.1.1.2 christos kctx->custom, kctx->custom_len, block_len) 356 1.1.1.2 christos && EVP_DigestUpdate(ctx, out, out_len) 357 1.1.1.2 christos && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len); 358 1.1 christos OPENSSL_free(out); 359 1.1 christos return res; 360 1.1 christos } 361 1.1 christos 362 1.1 christos static int kmac_update(void *vmacctx, const unsigned char *data, 363 1.1.1.2 christos size_t datalen) 364 1.1 christos { 365 1.1 christos struct kmac_data_st *kctx = vmacctx; 366 1.1 christos 367 1.1 christos return EVP_DigestUpdate(kctx->ctx, data, datalen); 368 1.1 christos } 369 1.1 christos 370 1.1 christos static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl, 371 1.1.1.2 christos size_t outsize) 372 1.1 christos { 373 1.1 christos struct kmac_data_st *kctx = vmacctx; 374 1.1 christos EVP_MD_CTX *ctx = kctx->ctx; 375 1.1 christos size_t lbits, len; 376 1.1 christos unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN]; 377 1.1 christos int ok; 378 1.1 christos 379 1.1 christos if (!ossl_prov_is_running()) 380 1.1 christos return 0; 381 1.1 christos 382 1.1 christos /* KMAC XOF mode sets the encoded length to 0 */ 383 1.1 christos lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8)); 384 1.1 christos 385 1.1 christos ok = right_encode(encoded_outlen, sizeof(encoded_outlen), &len, lbits) 386 1.1 christos && EVP_DigestUpdate(ctx, encoded_outlen, len) 387 1.1 christos && EVP_DigestFinalXOF(ctx, out, kctx->out_len); 388 1.1 christos *outl = kctx->out_len; 389 1.1 christos return ok; 390 1.1 christos } 391 1.1 christos 392 1.1 christos static const OSSL_PARAM known_gettable_ctx_params[] = { 393 1.1 christos OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), 394 1.1 christos OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL), 395 1.1 christos OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 396 1.1.1.2 christos OSSL_PARAM_END 397 1.1 christos }; 398 1.1 christos static const OSSL_PARAM *kmac_gettable_ctx_params(ossl_unused void *ctx, 399 1.1.1.2 christos ossl_unused void *provctx) 400 1.1 christos { 401 1.1 christos return known_gettable_ctx_params; 402 1.1 christos } 403 1.1 christos 404 1.1 christos static int kmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[]) 405 1.1 christos { 406 1.1 christos struct kmac_data_st *kctx = vmacctx; 407 1.1 christos OSSL_PARAM *p; 408 1.1 christos int sz; 409 1.1 christos 410 1.1 christos if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL 411 1.1.1.2 christos && !OSSL_PARAM_set_size_t(p, kctx->out_len)) 412 1.1 christos return 0; 413 1.1 christos 414 1.1 christos if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL) { 415 1.1 christos sz = EVP_MD_block_size(ossl_prov_digest_md(&kctx->digest)); 416 1.1 christos if (!OSSL_PARAM_set_int(p, sz)) 417 1.1 christos return 0; 418 1.1 christos } 419 1.1 christos 420 1.1 christos if (!OSSL_FIPS_IND_GET_CTX_PARAM(kctx, params)) 421 1.1 christos return 0; 422 1.1 christos 423 1.1 christos return 1; 424 1.1 christos } 425 1.1 christos 426 1.1 christos static const OSSL_PARAM known_settable_ctx_params[] = { 427 1.1 christos OSSL_PARAM_int(OSSL_MAC_PARAM_XOF, NULL), 428 1.1 christos OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), 429 1.1 christos OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), 430 1.1 christos OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0), 431 1.1 christos OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_MAC_PARAM_FIPS_NO_SHORT_MAC) 432 1.1.1.2 christos OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_MAC_PARAM_FIPS_KEY_CHECK) 433 1.1.1.2 christos OSSL_PARAM_END 434 1.1 christos }; 435 1.1 christos static const OSSL_PARAM *kmac_settable_ctx_params(ossl_unused void *ctx, 436 1.1.1.2 christos ossl_unused void *provctx) 437 1.1 christos { 438 1.1 christos return known_settable_ctx_params; 439 1.1 christos } 440 1.1 christos 441 1.1 christos /* 442 1.1 christos * The following params can be set any time before final(): 443 1.1 christos * - "outlen" or "size": The requested output length. 444 1.1 christos * - "xof": If set, this indicates that right_encoded(0) 445 1.1 christos * is part of the digested data, otherwise it 446 1.1 christos * uses right_encoded(requested output length). 447 1.1 christos * 448 1.1 christos * All other params should be set before init(). 449 1.1 christos */ 450 1.1 christos static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params) 451 1.1 christos { 452 1.1 christos struct kmac_data_st *kctx = vmacctx; 453 1.1 christos const OSSL_PARAM *p; 454 1.1 christos 455 1.1 christos if (ossl_param_is_empty(params)) 456 1.1 christos return 1; 457 1.1 christos 458 1.1 christos if (!OSSL_FIPS_IND_SET_CTX_PARAM(kctx, OSSL_FIPS_IND_SETTABLE0, params, 459 1.1.1.2 christos OSSL_MAC_PARAM_FIPS_NO_SHORT_MAC)) 460 1.1 christos return 0; 461 1.1 christos if (!OSSL_FIPS_IND_SET_CTX_PARAM(kctx, OSSL_FIPS_IND_SETTABLE1, params, 462 1.1.1.2 christos OSSL_MAC_PARAM_FIPS_KEY_CHECK)) 463 1.1 christos return 0; 464 1.1 christos 465 1.1 christos if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_XOF)) != NULL 466 1.1 christos && !OSSL_PARAM_get_int(p, &kctx->xof_mode)) 467 1.1 christos return 0; 468 1.1 christos if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) { 469 1.1 christos size_t sz = 0; 470 1.1 christos 471 1.1 christos if (!OSSL_PARAM_get_size_t(p, &sz)) 472 1.1 christos return 0; 473 1.1 christos if (sz > KMAC_MAX_OUTPUT_LEN) { 474 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH); 475 1.1 christos return 0; 476 1.1 christos } 477 1.1 christos #ifdef FIPS_MODULE 478 1.1 christos /* SP 800-185 8.4.2 mandates a minimum of 32 bits of output */ 479 1.1 christos if (sz < 32 / 8) { 480 1.1 christos if (!OSSL_FIPS_IND_ON_UNAPPROVED(kctx, OSSL_FIPS_IND_SETTABLE0, 481 1.1.1.2 christos PROV_LIBCTX_OF(kctx->provctx), 482 1.1.1.2 christos "KMAC", "length", 483 1.1.1.2 christos ossl_fips_config_no_short_mac)) { 484 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH); 485 1.1 christos return 0; 486 1.1 christos } 487 1.1 christos } 488 1.1 christos #endif 489 1.1 christos kctx->out_len = sz; 490 1.1 christos } 491 1.1 christos if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL 492 1.1.1.2 christos && !kmac_setkey(kctx, p->data, p->data_size)) 493 1.1 christos return 0; 494 1.1 christos if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM)) 495 1.1 christos != NULL) { 496 1.1 christos if (p->data_size > KMAC_MAX_CUSTOM) { 497 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH); 498 1.1 christos return 0; 499 1.1 christos } 500 1.1 christos if (!encode_string(kctx->custom, sizeof(kctx->custom), &kctx->custom_len, 501 1.1.1.2 christos p->data, p->data_size)) 502 1.1 christos return 0; 503 1.1 christos } 504 1.1 christos return 1; 505 1.1 christos } 506 1.1 christos 507 1.1 christos /* Encoding/Padding Methods. */ 508 1.1 christos 509 1.1 christos /* Returns the number of bytes required to store 'bits' into a byte array */ 510 1.1 christos static unsigned int get_encode_size(size_t bits) 511 1.1 christos { 512 1.1 christos unsigned int cnt = 0, sz = sizeof(size_t); 513 1.1 christos 514 1.1 christos while (bits && (cnt < sz)) { 515 1.1 christos ++cnt; 516 1.1 christos bits >>= 8; 517 1.1 christos } 518 1.1 christos /* If bits is zero 1 byte is required */ 519 1.1 christos if (cnt == 0) 520 1.1 christos cnt = 1; 521 1.1 christos return cnt; 522 1.1 christos } 523 1.1 christos 524 1.1 christos /* 525 1.1 christos * Convert an integer into bytes . The number of bytes is appended 526 1.1 christos * to the end of the buffer. Returns an array of bytes 'out' of size 527 1.1 christos * *out_len. 528 1.1 christos * 529 1.1 christos * e.g if bits = 32, out[2] = { 0x20, 0x01 } 530 1.1 christos */ 531 1.1 christos static int right_encode(unsigned char *out, size_t out_max_len, size_t *out_len, 532 1.1.1.2 christos size_t bits) 533 1.1 christos { 534 1.1 christos unsigned int len = get_encode_size(bits); 535 1.1 christos int i; 536 1.1 christos 537 1.1 christos if (len >= out_max_len) { 538 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE); 539 1.1 christos return 0; 540 1.1 christos } 541 1.1 christos 542 1.1 christos /* MSB's are at the start of the bytes array */ 543 1.1 christos for (i = len - 1; i >= 0; --i) { 544 1.1 christos out[i] = (unsigned char)(bits & 0xFF); 545 1.1 christos bits >>= 8; 546 1.1 christos } 547 1.1 christos /* Tack the length onto the end */ 548 1.1 christos out[len] = (unsigned char)len; 549 1.1 christos 550 1.1 christos /* The Returned length includes the tacked on byte */ 551 1.1 christos *out_len = len + 1; 552 1.1 christos return 1; 553 1.1 christos } 554 1.1 christos 555 1.1 christos /* 556 1.1 christos * Encodes a string with a left encoded length added. Note that the 557 1.1 christos * in_len is converted to bits (*8). 558 1.1 christos * 559 1.1 christos * e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 } 560 1.1 christos * len bits K M A C 561 1.1 christos */ 562 1.1 christos static int encode_string(unsigned char *out, size_t out_max_len, size_t *out_len, 563 1.1.1.2 christos const unsigned char *in, size_t in_len) 564 1.1 christos { 565 1.1 christos if (in == NULL) { 566 1.1 christos *out_len = 0; 567 1.1 christos } else { 568 1.1 christos size_t i, bits, len, sz; 569 1.1 christos 570 1.1 christos bits = 8 * in_len; 571 1.1 christos len = get_encode_size(bits); 572 1.1 christos sz = 1 + len + in_len; 573 1.1 christos 574 1.1 christos if (sz > out_max_len) { 575 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE); 576 1.1 christos return 0; 577 1.1 christos } 578 1.1 christos 579 1.1 christos out[0] = (unsigned char)len; 580 1.1 christos for (i = len; i > 0; --i) { 581 1.1 christos out[i] = (bits & 0xFF); 582 1.1 christos bits >>= 8; 583 1.1 christos } 584 1.1 christos memcpy(out + len + 1, in, in_len); 585 1.1 christos *out_len = sz; 586 1.1 christos } 587 1.1 christos return 1; 588 1.1 christos } 589 1.1 christos 590 1.1 christos /* 591 1.1 christos * Returns a zero padded encoding of the inputs in1 and an optional 592 1.1 christos * in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'. 593 1.1 christos * The value of w is in bytes (< 256). 594 1.1 christos * 595 1.1 christos * The returned output is: 596 1.1 christos * zero_padded(multiple of w, (left_encode(w) || in1 [|| in2]) 597 1.1 christos */ 598 1.1 christos static int bytepad(unsigned char *out, size_t *out_len, 599 1.1.1.2 christos const unsigned char *in1, size_t in1_len, 600 1.1.1.2 christos const unsigned char *in2, size_t in2_len, size_t w) 601 1.1 christos { 602 1.1 christos int len; 603 1.1 christos unsigned char *p = out; 604 1.1 christos int sz = w; 605 1.1 christos 606 1.1 christos if (out == NULL) { 607 1.1 christos if (out_len == NULL) { 608 1.1 christos ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 609 1.1 christos return 0; 610 1.1 christos } 611 1.1 christos sz = 2 + in1_len + (in2 != NULL ? in2_len : 0); 612 1.1 christos *out_len = (sz + w - 1) / w * w; 613 1.1 christos return 1; 614 1.1 christos } 615 1.1 christos 616 1.1 christos if (!ossl_assert(w <= 255)) 617 1.1 christos return 0; 618 1.1 christos 619 1.1 christos /* Left encoded w */ 620 1.1 christos *p++ = 1; 621 1.1 christos *p++ = (unsigned char)w; 622 1.1 christos /* || in1 */ 623 1.1 christos memcpy(p, in1, in1_len); 624 1.1 christos p += in1_len; 625 1.1 christos /* [ || in2 ] */ 626 1.1 christos if (in2 != NULL && in2_len > 0) { 627 1.1 christos memcpy(p, in2, in2_len); 628 1.1 christos p += in2_len; 629 1.1 christos } 630 1.1 christos /* Figure out the pad size (divisible by w) */ 631 1.1 christos len = p - out; 632 1.1 christos sz = (len + w - 1) / w * w; 633 1.1 christos /* zero pad the end of the buffer */ 634 1.1 christos if (sz != len) 635 1.1 christos memset(p, 0, sz - len); 636 1.1 christos if (out_len != NULL) 637 1.1 christos *out_len = sz; 638 1.1 christos return 1; 639 1.1 christos } 640 1.1 christos 641 1.1 christos /* Returns out = bytepad(encode_string(in), w) */ 642 1.1 christos static int kmac_bytepad_encode_key(unsigned char *out, size_t out_max_len, 643 1.1.1.2 christos size_t *out_len, 644 1.1.1.2 christos const unsigned char *in, size_t in_len, 645 1.1.1.2 christos size_t w) 646 1.1 christos { 647 1.1 christos unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN]; 648 1.1 christos size_t tmp_len; 649 1.1 christos 650 1.1 christos if (!encode_string(tmp, sizeof(tmp), &tmp_len, in, in_len)) 651 1.1 christos return 0; 652 1.1 christos if (!bytepad(NULL, out_len, tmp, tmp_len, NULL, 0, w)) 653 1.1 christos return 0; 654 1.1 christos if (!ossl_assert(*out_len <= out_max_len)) 655 1.1 christos return 0; 656 1.1 christos return bytepad(out, NULL, tmp, tmp_len, NULL, 0, w); 657 1.1 christos } 658 1.1 christos 659 1.1 christos #define IMPLEMENT_KMAC_TABLE(size, funcname, newname) \ 660 1.1.1.2 christos const OSSL_DISPATCH ossl_kmac##size##_##funcname[] = { \ 661 1.1.1.2 christos { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac##size##_##newname }, \ 662 1.1.1.2 christos { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup }, \ 663 1.1.1.2 christos { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free }, \ 664 1.1.1.2 christos { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init }, \ 665 1.1.1.2 christos { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update }, \ 666 1.1.1.2 christos { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final }, \ 667 1.1.1.2 christos { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, \ 668 1.1.1.2 christos (void (*)(void))kmac_gettable_ctx_params }, \ 669 1.1.1.2 christos { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))kmac_get_ctx_params }, \ 670 1.1.1.2 christos { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, \ 671 1.1.1.2 christos (void (*)(void))kmac_settable_ctx_params }, \ 672 1.1.1.2 christos { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params }, \ 673 1.1.1.2 christos OSSL_DISPATCH_END \ 674 1.1.1.2 christos } 675 1.1 christos 676 1.1 christos #define KMAC_TABLE(size) IMPLEMENT_KMAC_TABLE(size, functions, new) 677 1.1 christos 678 1.1 christos KMAC_TABLE(128); 679 1.1 christos KMAC_TABLE(256); 680 1.1 christos 681 1.1 christos #ifdef FIPS_MODULE 682 1.1.1.2 christos #define KMAC_INTERNAL_TABLE(size) \ 683 1.1.1.2 christos static OSSL_FUNC_mac_newctx_fn kmac##size##_internal_new; \ 684 1.1.1.2 christos static void *kmac##size##_internal_new(void *provctx) \ 685 1.1.1.2 christos { \ 686 1.1.1.2 christos struct kmac_data_st *macctx = kmac##size##_new(provctx); \ 687 1.1.1.2 christos \ 688 1.1.1.2 christos if (macctx != NULL) \ 689 1.1.1.2 christos macctx->internal = 1; \ 690 1.1.1.2 christos return macctx; \ 691 1.1.1.2 christos } \ 692 1.1.1.2 christos IMPLEMENT_KMAC_TABLE(size, internal_functions, internal_new) 693 1.1 christos 694 1.1 christos KMAC_INTERNAL_TABLE(128); 695 1.1 christos KMAC_INTERNAL_TABLE(256); 696 1.1 christos #endif /* FIPS_MODULE */ 697