/
githubmirror
/
ipxe
Обзор
Документация
Войти
/
githubmirror
/
ipxe
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/crypto/hkdf.c
125 строк
4 KB
Michael Brown
[crypto] Add assertion on HKDF output length
09 авг 2026, 12:50
09 авг 2026, 12:50
2fa9f8b
Код
Авторство
О чём код?
/* * Copyright (C) 2026 Michael Brown <mbrown@fensystems.co.uk>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * You can also choose to distribute this program under the terms of * the Unmodified Binary Distribution Licence (as given in the file * COPYING.UBDL), provided that you have satisfied its requirements. */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); FILE_SECBOOT ( PERMITTED ); /** @file * * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) * * The algorithm is defined in RFC 5869, with its usage by TLS 1.3 * documented in RFC 8446 section 7.1. * */ #include <stdint.h> #include <string.h> #include <assert.h> #include <ipxe/crypto.h> #include <ipxe/hmac.h> #include <ipxe/hkdf.h> /** * Extract fixed-length pseudorandom key * * @v digest Digest algorithm * @v salt Salt value (or NULL) * @v salt_len Length of salt value * @v ikm Input keying material * @v ikm_len Length of input keying material * @v prk Pseudorandom key to fill in * * The salt and input keying material are allowed to overlap the * buffer that will be filled in with the pseudorandom key. */ void hkdf_extract ( struct digest_algorithm *digest, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len, void *prk ) { uint8_t ctx[ hmac_ctxsize ( digest ) ]; uint8_t zero[ digest->digestsize ]; /* Use all-zero salt if not specified */ if ( ! salt ) { assert ( salt_len == 0 ); memset ( zero, 0, sizeof ( zero ) ); salt = zero; salt_len = sizeof ( zero ); } /* Calculate pseudorandom key */ hmac_init ( digest, ctx, salt, salt_len ); hmac_update ( digest, ctx, ikm, ikm_len ); hmac_final ( digest, ctx, prk ); } /** * Expand pseudorandom key * * @v digest Digest algorithm * @v prk Pseudorandom key * @v info Additional information (or NULL) * @v info_len Length of additional information * @v out Output keying material * @v len Length of output keying material * * The pseudorandom key and additional information are allowed to * overlap the buffer that will be filled in with the output keying * material, provided that the length of the output keying material is * less than or equal to the length of the pseudorandom key. * * In particular, this allows hkdf_expand() to be used to create a new * generation of pseudorandom key (i.e. to have the output keying * material overwrite the existing pseudorandom key). */ void hkdf_expand ( struct digest_algorithm *digest, const void *prk, const void *info, size_t info_len, void *out, size_t len ) { size_t digestsize = digest->digestsize; uint8_t ctx[ hmac_ctxsize ( digest ) ]; uint8_t hash[digestsize]; uint8_t index = 0; size_t frag_len; /* Sanity check */ assert ( len <= ( digestsize * 0xff /* max index */ ) ); /* Construct output keying material */ while ( len ) { /* Calculate T(n) */ hmac_init ( digest, ctx, prk, digestsize ); if ( index++ ) hmac_update ( digest, ctx, hash, digestsize ); hmac_update ( digest, ctx, info, info_len ); hmac_update ( digest, ctx, &index, sizeof ( index ) ); hmac_final ( digest, ctx, hash ); /* Copy to output buffer */ frag_len = len; if ( frag_len > digestsize ) frag_len = digestsize; memcpy ( out, hash, frag_len ); out += frag_len; len -= frag_len; } }