mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-21 10:09:57 +01:00
Add kmac.c.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
e17d822492
commit
5a25b27860
@ -205,11 +205,7 @@ agent_hybrid_kem_decap (ctrl_t ctrl, const char *desc_text, int kemid,
|
||||
const unsigned char *mlkem_ct;
|
||||
unsigned char mlkem_ss[GCRY_KEM_MLKEM768_SHARED_LEN];
|
||||
|
||||
gcry_buffer_t iov[13];
|
||||
unsigned char head136[2];
|
||||
unsigned char headK[3];
|
||||
const unsigned char pad[94] = { 0 };
|
||||
unsigned char right_encode_L[3];
|
||||
gcry_buffer_t iov[6];
|
||||
|
||||
unsigned char kekkey[32];
|
||||
size_t kekkeylen = 32; /* AES-256 is mandatory */
|
||||
@ -361,68 +357,34 @@ agent_hybrid_kem_decap (ctrl_t ctrl, const char *desc_text, int kemid,
|
||||
// newX = bytepad(encode_string(K), 136) || X || right_encode(L)
|
||||
// cSHAKE256(newX,L,"KMAC",S)
|
||||
|
||||
iov[0].data = "KMAC";
|
||||
iov[0].data = "\x00\x00\x00\x01"; /* Counter */
|
||||
iov[0].off = 0;
|
||||
iov[0].len = 4;
|
||||
|
||||
iov[1].data = "KDF";
|
||||
iov[1].data = ecc_ss;
|
||||
iov[1].off = 0;
|
||||
iov[1].len = 3;
|
||||
iov[1].len = 32;
|
||||
|
||||
head136[0] = 1;
|
||||
head136[1] = 136;
|
||||
iov[2].data = head136;
|
||||
iov[2].data = (unsigned char *)ecc_ct;
|
||||
iov[2].off = 0;
|
||||
iov[2].len = 2;
|
||||
iov[2].len = 32;
|
||||
|
||||
headK[0] = 2;
|
||||
headK[1] = (37*8)>>8;
|
||||
headK[2] = (37*8)&0xff;
|
||||
iov[3].data = headK;
|
||||
iov[3].data = mlkem_ss;
|
||||
iov[3].off = 0;
|
||||
iov[3].len = 3;
|
||||
iov[3].len = GCRY_KEM_MLKEM768_SHARED_LEN;
|
||||
|
||||
iov[4].data = "OpenPGPCompositeKeyDerivationFunction";
|
||||
iov[4].data = (unsigned char *)mlkem_ct;
|
||||
iov[4].off = 0;
|
||||
iov[4].len = 37;
|
||||
iov[4].len = GCRY_KEM_MLKEM768_ENCAPS_LEN;
|
||||
|
||||
iov[5].data = (unsigned char *)pad;
|
||||
iov[5].data = (unsigned char *)fixedinfo;
|
||||
iov[5].off = 0;
|
||||
iov[5].len = sizeof (pad);
|
||||
iov[5].len = 1;
|
||||
|
||||
iov[6].data = "\x00\x00\x00\x01"; /* Counter */
|
||||
iov[6].off = 0;
|
||||
iov[6].len = 4;
|
||||
err = compute_kmac256 (kekkey, kekkeylen,
|
||||
"OpenPGPCompositeKeyDerivationFunction", 37,
|
||||
"KDF", 3, iov, 6);
|
||||
|
||||
iov[7].data = ecc_ss;
|
||||
iov[7].off = 0;
|
||||
iov[7].len = 32;
|
||||
|
||||
iov[8].data = (unsigned char *)ecc_ct;
|
||||
iov[8].off = 0;
|
||||
iov[8].len = 32;
|
||||
|
||||
iov[9].data = mlkem_ss;
|
||||
iov[9].off = 0;
|
||||
iov[9].len = GCRY_KEM_MLKEM768_SHARED_LEN;
|
||||
|
||||
iov[10].data = (unsigned char *)mlkem_ct;
|
||||
iov[10].off = 0;
|
||||
iov[10].len = GCRY_KEM_MLKEM768_ENCAPS_LEN;
|
||||
|
||||
iov[11].data = (unsigned char *)fixedinfo;
|
||||
iov[11].off = 0;
|
||||
iov[11].len = 1;
|
||||
|
||||
right_encode_L[0] = (kekkeylen * 8) >> 8;
|
||||
right_encode_L[1] = (kekkeylen * 8) & 0xff;
|
||||
right_encode_L[2] = 2;
|
||||
iov[12].data = right_encode_L;
|
||||
iov[12].off = 0;
|
||||
iov[12].len = 3;
|
||||
|
||||
err = gcry_md_hash_buffers_extract (GCRY_MD_CSHAKE256, 0, kekkey, kekkeylen,
|
||||
iov, 13);
|
||||
mpi_release (ecc_ct_mpi);
|
||||
mpi_release (mlkem_ct_mpi);
|
||||
|
||||
|
@ -97,8 +97,8 @@ common_sources = \
|
||||
openpgp-fpr.c \
|
||||
comopt.c comopt.h \
|
||||
compliance.c compliance.h \
|
||||
pkscreening.c pkscreening.h
|
||||
|
||||
pkscreening.c pkscreening.h \
|
||||
kmac.c
|
||||
|
||||
if HAVE_W32_SYSTEM
|
||||
common_sources += w32-reg.c w32-cmdline.c
|
||||
|
132
common/kmac.c
Normal file
132
common/kmac.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* kmac.c - Keccak based MAC
|
||||
* Copyright (C) 2024 g10 Code GmbH.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute and/or modify this
|
||||
* part of GnuPG under the terms of either
|
||||
*
|
||||
* - the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or
|
||||
*
|
||||
* - the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or both in parallel, as here.
|
||||
*
|
||||
* GnuPG 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 copies of the GNU General Public License
|
||||
* and the GNU Lesser General Public License along with this program;
|
||||
* if not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gpg-error.h>
|
||||
#include <gcrypt.h>
|
||||
#include "mischelp.h"
|
||||
|
||||
#define KECCAK512_BLOCKSIZE 136
|
||||
gpg_error_t
|
||||
compute_kmac256 (void *digest, size_t digestlen,
|
||||
const void *key, size_t keylen,
|
||||
const void *custom, size_t customlen,
|
||||
gcry_buffer_t *data_iov, int data_iovlen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_buffer_t iov[20];
|
||||
const unsigned char headPAD[2] = { 1, KECCAK512_BLOCKSIZE };
|
||||
unsigned char headK[3];
|
||||
const unsigned char pad[KECCAK512_BLOCKSIZE] = { 0 };
|
||||
unsigned char right_encode_L[3];
|
||||
unsigned int len;
|
||||
int iovcnt;
|
||||
|
||||
if (data_iovlen >= DIM(iov) - 6)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
|
||||
/* Check the validity conditions of NIST SP 800-185 */
|
||||
if (keylen >= 255 || customlen >= 255 || digestlen >= 255)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
|
||||
iovcnt = 0;
|
||||
iov[iovcnt].data = "KMAC";
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = 4;
|
||||
iovcnt++;
|
||||
|
||||
iov[iovcnt].data = (void *)custom;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = customlen;
|
||||
iovcnt++;
|
||||
|
||||
iov[iovcnt].data = (void *)headPAD;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = sizeof (headPAD);
|
||||
iovcnt++;
|
||||
|
||||
if (keylen < 32)
|
||||
{
|
||||
headK[0] = 1;
|
||||
headK[1] = (keylen*8)&0xff;
|
||||
iov[iovcnt].data = headK;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
headK[0] = 2;
|
||||
headK[1] = (keylen*8)>>8;
|
||||
headK[2] = (keylen*8)&0xff;
|
||||
iov[iovcnt].data = headK;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = 3;
|
||||
}
|
||||
iovcnt++;
|
||||
|
||||
iov[iovcnt].data = (void *)key;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = keylen;
|
||||
iovcnt++;
|
||||
|
||||
len = iov[2].len + iov[3].len + iov[4].len;
|
||||
len %= KECCAK512_BLOCKSIZE;
|
||||
|
||||
iov[iovcnt].data = (unsigned char *)pad;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = sizeof (pad) - len;
|
||||
iovcnt++;
|
||||
|
||||
memcpy (&iov[iovcnt], data_iov, data_iovlen * sizeof (gcry_buffer_t));
|
||||
iovcnt += data_iovlen;
|
||||
|
||||
if (digestlen < 32)
|
||||
{
|
||||
right_encode_L[0] = (digestlen * 8) & 0xff;
|
||||
right_encode_L[1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_encode_L[0] = (digestlen * 8) >> 8;
|
||||
right_encode_L[1] = (digestlen * 8) & 0xff;
|
||||
right_encode_L[2] = 2;
|
||||
}
|
||||
|
||||
iov[iovcnt].data = right_encode_L;
|
||||
iov[iovcnt].off = 0;
|
||||
iov[iovcnt].len = 3;
|
||||
iovcnt++;
|
||||
|
||||
err = gcry_md_hash_buffers_extract (GCRY_MD_CSHAKE256, 0,
|
||||
digest, digestlen, iov, iovcnt);
|
||||
return err;
|
||||
}
|
@ -298,6 +298,12 @@ char *gnupg_get_help_string (const char *key, int only_current_locale);
|
||||
/*-- localename.c --*/
|
||||
const char *gnupg_messages_locale_name (void);
|
||||
|
||||
/*-- kmac.c --*/
|
||||
gpg_error_t compute_kmac256 (void *digest, size_t digestlen,
|
||||
const void *key, size_t keylen,
|
||||
const void *custom, size_t customlen,
|
||||
gcry_buffer_t *data_iov, int data_iovlen);
|
||||
|
||||
/*-- miscellaneous.c --*/
|
||||
|
||||
/* This function is called at startup to tell libgcrypt to use our own
|
||||
|
Loading…
x
Reference in New Issue
Block a user