diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 34de75bd..2277815f 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -1,270 +1,271 @@
# Makefile for cipher modules
# Copyright (C) 1998, 1999, 2000, 2001, 2002,
# 2003, 2009 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see .
# Process this file with automake to produce Makefile.in
# Need to include ../src in addition to top_srcdir because gcrypt.h is
# a built header.
AM_CPPFLAGS = -I../src -I$(top_srcdir)/src -I../mpi -I$(top_srcdir)/mpi
AM_CFLAGS = $(GPG_ERROR_CFLAGS)
AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
EXTRA_DIST = gost-s-box.c
CLEANFILES = gost-s-box
DISTCLEANFILES = gost-sb.h
noinst_LTLIBRARIES = libcipher.la
GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ \
@GCRYPT_DIGESTS@ @GCRYPT_KDFS@
libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
libcipher_la_LIBADD = $(GCRYPT_MODULES)
libcipher_la_SOURCES = \
cipher.c cipher-internal.h \
cipher-cbc.c \
cipher-cfb.c \
cipher-ofb.c \
cipher-ctr.c \
cipher-aeswrap.c \
cipher-ccm.c \
cipher-cmac.c \
cipher-gcm.c \
cipher-poly1305.c \
cipher-ocb.c \
cipher-xts.c \
cipher-eax.c \
cipher-siv.c \
cipher-gcm-siv.c \
cipher-selftest.c cipher-selftest.h \
pubkey.c pubkey-internal.h pubkey-util.c \
- pkey.c pkey-internal.h pkey-ed25519.c pkey-ed448.c \
+ pkey.c pkey-internal.h \
+ pkey-ed25519.c pkey-ed448.c pkey-rsapss.c \
md.c \
mac.c mac-internal.h \
mac-hmac.c mac-cmac.c mac-gmac.c mac-poly1305.c \
poly1305.c poly1305-internal.h \
poly1305-s390x.S \
kdf.c kdf-internal.h \
bithelp.h \
bufhelp.h \
primegen.c \
hash-common.c hash-common.h \
dsa-common.c rsa-common.c \
sha1.h
EXTRA_libcipher_la_SOURCES = \
asm-common-aarch64.h \
asm-common-amd64.h \
asm-common-s390x.h \
asm-inline-s390x.h \
asm-poly1305-aarch64.h \
asm-poly1305-amd64.h \
asm-poly1305-s390x.h \
arcfour.c arcfour-amd64.S \
blowfish.c blowfish-amd64.S blowfish-arm.S \
cast5.c cast5-amd64.S cast5-arm.S \
chacha20.c chacha20-amd64-ssse3.S chacha20-amd64-avx2.S \
chacha20-armv7-neon.S chacha20-aarch64.S \
chacha20-ppc.c chacha20-s390x.S \
cipher-gcm-ppc.c cipher-gcm-intel-pclmul.c cipher-gcm-armv7-neon.S \
cipher-gcm-armv8-aarch32-ce.S cipher-gcm-armv8-aarch64-ce.S \
crc.c crc-intel-pclmul.c crc-armv8-ce.c \
crc-armv8-aarch64-ce.S \
crc-ppc.c \
des.c des-amd64.S \
dsa.c \
elgamal.c \
ecc.c ecc-curves.c ecc-misc.c ecc-common.h \
ecc-ecdh.c ecc-ecdsa.c ecc-eddsa.c ecc-gost.c ecc-sm2.c \
idea.c \
gost28147.c gost.h \
gostr3411-94.c \
md4.c \
md5.c \
rijndael.c rijndael-internal.h rijndael-tables.h \
rijndael-aesni.c rijndael-padlock.c \
rijndael-amd64.S rijndael-arm.S \
rijndael-ssse3-amd64.c rijndael-ssse3-amd64-asm.S \
rijndael-vaes.c rijndael-vaes-avx2-amd64.S \
rijndael-armv8-ce.c rijndael-armv8-aarch32-ce.S \
rijndael-armv8-aarch64-ce.S rijndael-aarch64.S \
rijndael-ppc.c rijndael-ppc9le.c \
rijndael-ppc-common.h rijndael-ppc-functions.h \
rijndael-s390x.c \
rmd160.c \
rsa.c \
salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \
scrypt.c \
seed.c \
serpent.c serpent-sse2-amd64.S \
sm4.c sm4-aesni-avx-amd64.S sm4-aesni-avx2-amd64.S \
serpent-avx2-amd64.S serpent-armv7-neon.S \
sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \
sha1-avx2-bmi2-amd64.S sha1-armv7-neon.S sha1-armv8-aarch32-ce.S \
sha1-armv8-aarch64-ce.S sha1-intel-shaext.c \
sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S \
sha256-avx2-bmi2-amd64.S \
sha256-armv8-aarch32-ce.S sha256-armv8-aarch64-ce.S \
sha256-intel-shaext.c sha256-ppc.c \
sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S \
sha512-avx2-bmi2-amd64.S \
sha512-armv7-neon.S sha512-arm.S \
sha512-ppc.c sha512-ssse3-i386.c \
sm3.c \
keccak.c keccak_permute_32.h keccak_permute_64.h keccak-armv7-neon.S \
stribog.c \
tiger.c \
whirlpool.c whirlpool-sse2-amd64.S \
twofish.c twofish-amd64.S twofish-arm.S twofish-aarch64.S \
twofish-avx2-amd64.S \
rfc2268.c \
camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \
camellia-aesni-avx2-amd64.h camellia-vaes-avx2-amd64.S \
camellia-aesni-avx2-amd64.S camellia-arm.S camellia-aarch64.S \
blake2.c \
blake2b-amd64-avx2.S blake2s-amd64-avx.S
gost28147.lo: gost-sb.h
gost-sb.h: gost-s-box
./gost-s-box $@
gost-s-box: gost-s-box.c
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
$(CPPFLAGS_FOR_BUILD)-o $@ $(srcdir)/gost-s-box.c
if ENABLE_O_FLAG_MUNGING
o_flag_munging = sed -e 's/-O\([2-9sg][2-9sg]*\)/-O1/' -e 's/-Ofast/-O1/g'
else
o_flag_munging = cat
endif
# We need to lower the optimization for this module.
tiger.o: $(srcdir)/tiger.c Makefile
`echo $(COMPILE) -c $< | $(o_flag_munging) `
tiger.lo: $(srcdir)/tiger.c Makefile
`echo $(LTCOMPILE) -c $< | $(o_flag_munging) `
# We need to disable instrumentation for these modules as they use cc as
# thin assembly front-end and do not tolerate in-between function calls
# inserted by compiler as those functions may clobber the XMM registers.
if ENABLE_INSTRUMENTATION_MUNGING
instrumentation_munging = sed \
-e 's/-fsanitize[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \
-e 's/-fprofile[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \
-e 's/-fcoverage[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g'
else
instrumentation_munging = cat
endif
rijndael-aesni.o: $(srcdir)/rijndael-aesni.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
rijndael-aesni.lo: $(srcdir)/rijndael-aesni.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
rijndael-ssse3-amd64.o: $(srcdir)/rijndael-ssse3-amd64.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
rijndael-ssse3-amd64.lo: $(srcdir)/rijndael-ssse3-amd64.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
cipher-gcm-intel-pclmul.o: $(srcdir)/cipher-gcm-intel-pclmul.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
cipher-gcm-intel-pclmul.lo: $(srcdir)/cipher-gcm-intel-pclmul.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
sha1-intel-shaext.o: $(srcdir)/sha1-intel-shaext.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
sha1-intel-shaext.lo: $(srcdir)/sha1-intel-shaext.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
sha256-intel-shaext.o: $(srcdir)/sha256-intel-shaext.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
sha256-intel-shaext.lo: $(srcdir)/sha256-intel-shaext.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
sha256-ssse3-i386.o: $(srcdir)/sha256-ssse3-i386.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
sha256-ssse3-i386.lo: $(srcdir)/sha256-ssse3-i386.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
crc-intel-pclmul.o: $(srcdir)/crc-intel-pclmul.c Makefile
`echo $(COMPILE) -c $< | $(instrumentation_munging) `
crc-intel-pclmul.lo: $(srcdir)/crc-intel-pclmul.c Makefile
`echo $(LTCOMPILE) -c $< | $(instrumentation_munging) `
if ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS
ppc_vcrypto_cflags = -maltivec -mvsx -mcrypto
else
ppc_vcrypto_cflags =
endif
rijndael-ppc.o: $(srcdir)/rijndael-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
rijndael-ppc.lo: $(srcdir)/rijndael-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
rijndael-ppc9le.o: $(srcdir)/rijndael-ppc9le.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
rijndael-ppc9le.lo: $(srcdir)/rijndael-ppc9le.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
sha256-ppc.o: $(srcdir)/sha256-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
sha256-ppc.lo: $(srcdir)/sha256-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
sha512-ppc.o: $(srcdir)/sha512-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
sha512-ppc.lo: $(srcdir)/sha512-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
chacha20-ppc.o: $(srcdir)/chacha20-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
chacha20-ppc.lo: $(srcdir)/chacha20-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
crc-ppc.o: $(srcdir)/crc-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
crc-ppc.lo: $(srcdir)/crc-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
cipher-gcm-ppc.o: $(srcdir)/cipher-gcm-ppc.c Makefile
`echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
cipher-gcm-ppc.lo: $(srcdir)/cipher-gcm-ppc.c Makefile
`echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) `
diff --git a/cipher/pkey-ed25519.c b/cipher/pkey-ed25519.c
index e0edbf6d..a808a424 100644
--- a/cipher/pkey-ed25519.c
+++ b/cipher/pkey-ed25519.c
@@ -1,224 +1,224 @@
/* pkey-ed25519.c - PKEY API implementation for Ed25519
* Copyright (C) 2021 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
#include
#include
#include
#include
#include
#include
#include "g10lib.h"
#include "gcrypt-int.h"
#include "pkey-internal.h"
gcry_error_t
_gcry_pkey_ed25519_sign (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[],
int num_out, unsigned char *out[], size_t out_len[])
{
gcry_error_t err = 0;
gcry_sexp_t s_sk = NULL;
gcry_sexp_t s_msg= NULL;
gcry_sexp_t s_sig= NULL;
gcry_sexp_t s_tmp, s_tmp2;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
{
if (num_in != 2 || (h->flags & GCRY_PKEY_FLAG_PREHASH))
return gpg_error (GPG_ERR_INV_ARG);
}
else
{
if (num_in != 1)
return gpg_error (GPG_ERR_INV_ARG);
}
if (num_out != 2)
return gpg_error (GPG_ERR_INV_ARG);
- if (h->pk)
+ if (h->ecc.pk)
err = sexp_build (&s_sk, NULL,
"(private-key"
" (ecc"
" (curve \"Ed25519\")"
" (flags eddsa)"
" (q %b)"
" (d %b)))",
- (int)h->pk_len, h->pk,
- (int)h->sk_len, h->sk);
+ (int)h->ecc.pk_len, h->ecc.pk,
+ (int)h->ecc.sk_len, h->ecc.sk);
else
err = sexp_build (&s_sk, NULL,
"(private-key"
" (ecc"
" (curve \"Ed25519\")"
" (flags eddsa)"
" (d %b)))",
- (int)h->sk_len, h->sk);
+ (int)h->ecc.sk_len, h->ecc.sk);
if (err)
return err;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa)"
" (hash-algo sha512)"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[1], in[1]);
else if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa prehash)"
" (hash-algo sha512)"
" (value %b))", (int)in_len[0], in[0]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa)"
" (hash-algo sha512)"
" (value %b))", (int)in_len[0], in[0]);
if (err)
{
sexp_release (s_sk);
return err;
}
err = _gcry_pk_sign (&s_sig, s_msg, s_sk);
sexp_release (s_sk);
sexp_release (s_msg);
if (err)
return err;
out[0] = out[1] = NULL;
s_tmp2 = NULL;
s_tmp = sexp_find_token (s_sig, "sig-val", 0);
if (s_tmp)
{
s_tmp2 = s_tmp;
s_tmp = sexp_find_token (s_tmp2, "eddsa", 0);
if (s_tmp)
{
sexp_release (s_tmp2);
s_tmp2 = s_tmp;
s_tmp = sexp_find_token (s_tmp2, "r", 0);
if (s_tmp)
{
out[0] = sexp_nth_buffer (s_tmp, 1, &out_len[0]);
sexp_release (s_tmp);
}
s_tmp = sexp_find_token (s_tmp2, "s", 0);
if (s_tmp)
{
out[1] = sexp_nth_buffer (s_tmp, 1, &out_len[1]);
sexp_release (s_tmp);
}
}
}
sexp_release (s_tmp2);
if (out[0] == NULL || out[1] == NULL)
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
sexp_release (s_sig);
return err;
}
gcry_error_t
_gcry_pkey_ed25519_verify (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[])
{
gcry_error_t err = 0;
gcry_sexp_t s_pk = NULL;
gcry_sexp_t s_msg= NULL;
gcry_sexp_t s_sig= NULL;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
{
if (num_in != 4 || (h->flags & GCRY_PKEY_FLAG_PREHASH))
return gpg_error (GPG_ERR_INV_ARG);
}
else
{
if (num_in != 3)
return gpg_error (GPG_ERR_INV_ARG);
}
err = sexp_build (&s_pk, NULL,
"(public-key"
" (ecc"
" (curve \"Ed25519\")"
" (flags eddsa)"
" (q %b)))",
- (int)h->pk_len, h->pk);
+ (int)h->ecc.pk_len, h->ecc.pk);
if (err)
return err;
if (h->flags & GCRY_PKEY_FLAG_CONTEXT)
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa)"
" (hash-algo sha512)"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[3], in[3]);
else if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa prehash)"
" (hash-algo sha512)"
" (value %b))", (int)in_len[0], in[0]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (flags eddsa)"
" (hash-algo sha512)"
" (value %b))", (int)in_len[0], in[0]);
if (err)
{
sexp_release (s_pk);
return err;
}
err = sexp_build (&s_sig, NULL,
"(sig-val(eddsa(r %b)(s %b)))",
(int)in_len[1], in[1],
(int)in_len[2], in[2]);
if (err)
{
sexp_release (s_msg);
sexp_release (s_pk);
return err;
}
err = _gcry_pk_verify (s_sig, s_msg, s_pk);
sexp_release (s_sig);
sexp_release (s_msg);
sexp_release (s_pk);
return err;
}
diff --git a/cipher/pkey-ed448.c b/cipher/pkey-ed448.c
index 35dd39c4..9379adc1 100644
--- a/cipher/pkey-ed448.c
+++ b/cipher/pkey-ed448.c
@@ -1,233 +1,233 @@
/* pkey-ed448.c - PKEY API implementation for Ed448
* Copyright (C) 2021 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
#include
#include
#include
#include
#include
#include
#include "g10lib.h"
#include "gcrypt-int.h"
#include "pkey-internal.h"
gcry_error_t
_gcry_pkey_ed448_sign (gcry_pkey_hd_t h,
- int num_in, const unsigned char *const in[],
- const size_t in_len[],
- int num_out, unsigned char *out[], size_t out_len[])
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[],
+ int num_out, unsigned char *out[], size_t out_len[])
{
gcry_error_t err = 0;
gcry_sexp_t s_sk = NULL;
gcry_sexp_t s_msg= NULL;
gcry_sexp_t s_sig= NULL;
gcry_sexp_t s_tmp, s_tmp2;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
{
if (num_in != 2)
return gpg_error (GPG_ERR_INV_ARG);
}
else
{
if (num_in != 1)
return gpg_error (GPG_ERR_INV_ARG);
}
if (num_out != 2)
return gpg_error (GPG_ERR_INV_ARG);
- if (h->pk)
+ if (h->ecc.pk)
err = sexp_build (&s_sk, NULL,
"(private-key"
" (ecc"
" (curve \"Ed448\")"
" (q %b)"
" (d %b)))",
- (int)h->pk_len, h->pk,
- (int)h->sk_len, h->sk);
+ (int)h->ecc.pk_len, h->ecc.pk,
+ (int)h->ecc.sk_len, h->ecc.sk);
else
err = sexp_build (&s_sk, NULL,
"(private-key"
" (ecc"
" (curve \"Ed448\")"
" (d %b)))",
- (int)h->sk_len, h->sk);
+ (int)h->ecc.sk_len, h->ecc.sk);
if (err)
return err;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
{
if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags prehash)"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[1], in[1]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[1], in[1]);
}
else if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags prehash)"
" (value %b))", (int)in_len[0], in[0]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (value %b))", (int)in_len[0], in[0]);
if (err)
{
sexp_release (s_sk);
return err;
}
err = _gcry_pk_sign (&s_sig, s_msg, s_sk);
sexp_release (s_sk);
sexp_release (s_msg);
if (err)
return err;
out[0] = out[1] = NULL;
s_tmp2 = NULL;
s_tmp = sexp_find_token (s_sig, "sig-val", 0);
if (s_tmp)
{
s_tmp2 = s_tmp;
s_tmp = sexp_find_token (s_tmp2, "eddsa", 0);
if (s_tmp)
{
sexp_release (s_tmp2);
s_tmp2 = s_tmp;
s_tmp = sexp_find_token (s_tmp2, "r", 0);
if (s_tmp)
{
out[0] = sexp_nth_buffer (s_tmp, 1, &out_len[0]);
sexp_release (s_tmp);
}
s_tmp = sexp_find_token (s_tmp2, "s", 0);
if (s_tmp)
{
out[1] = sexp_nth_buffer (s_tmp, 1, &out_len[1]);
sexp_release (s_tmp);
}
}
}
sexp_release (s_tmp2);
if (out[0] == NULL || out[1] == NULL)
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
sexp_release (s_sig);
return err;
}
gcry_error_t
_gcry_pkey_ed448_verify (gcry_pkey_hd_t h,
- int num_in, const unsigned char *const in[],
- const size_t in_len[])
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[])
{
gcry_error_t err = 0;
gcry_sexp_t s_pk = NULL;
gcry_sexp_t s_msg= NULL;
gcry_sexp_t s_sig= NULL;
if ((h->flags & GCRY_PKEY_FLAG_CONTEXT))
{
if (num_in != 4)
return gpg_error (GPG_ERR_INV_ARG);
}
else
{
if (num_in != 3)
return gpg_error (GPG_ERR_INV_ARG);
}
err = sexp_build (&s_pk, NULL,
"(public-key"
" (ecc"
" (curve \"Ed448\")"
" (q %b)))",
- (int)h->pk_len, h->pk);
+ (int)h->ecc.pk_len, h->ecc.pk);
if (err)
return err;
if (h->flags & GCRY_PKEY_FLAG_CONTEXT)
{
if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags prehash)"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[3], in[3]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (value %b)"
" (label %b))",
(int)in_len[0], in[0],
(int)in_len[3], in[3]);
}
else if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
"(data"
" (flags prehash)"
" (value %b))", (int)in_len[0], in[0]);
else
err = sexp_build (&s_msg, NULL,
"(data"
" (value %b))", (int)in_len[0], in[0]);
if (err)
{
sexp_release (s_pk);
return err;
}
err = sexp_build (&s_sig, NULL,
"(sig-val(eddsa(r %b)(s %b)))",
(int)in_len[1], in[1],
(int)in_len[2], in[2]);
if (err)
{
sexp_release (s_msg);
sexp_release (s_pk);
return err;
}
err = _gcry_pk_verify (s_sig, s_msg, s_pk);
sexp_release (s_sig);
sexp_release (s_msg);
sexp_release (s_pk);
return err;
}
diff --git a/cipher/pkey-internal.h b/cipher/pkey-internal.h
index a63206ed..ae0e106c 100644
--- a/cipher/pkey-internal.h
+++ b/cipher/pkey-internal.h
@@ -1,55 +1,84 @@
/* pkey-internal.h - Internal defs for pkey.c
* Copyright (C) 2021 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
gcry_error_t _gcry_pkey_ed25519_sign (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[],
int num_out, unsigned char *out[],
size_t out_len[]);
gcry_error_t _gcry_pkey_ed25519_verify (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[]);
gcry_error_t _gcry_pkey_ed448_sign (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[],
int num_out, unsigned char *out[],
size_t out_len[]);
gcry_error_t _gcry_pkey_ed448_verify (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
const size_t in_len[]);
+gcry_error_t _gcry_pkey_rsapss_sign (gcry_pkey_hd_t h,
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[],
+ int num_out, unsigned char *out[],
+ size_t out_len[]);
-struct gcry_pkey_handle {
- int algo;
- unsigned int flags;
-
- /* FIXME: Use of union would be better, here. */
+gcry_error_t _gcry_pkey_rsapss_verify (gcry_pkey_hd_t h,
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[]);
+struct pkey_ecc {
int curve;
unsigned char *pk;
size_t pk_len;
unsigned char *sk;
size_t sk_len;
};
+
+struct pkey_rsa {
+ int scheme;
+
+ int md_algo;
+
+ unsigned char *n;
+ size_t n_len;
+
+ unsigned char *e;
+ size_t e_len;
+
+ unsigned char *d;
+ size_t d_len;
+};
+
+struct gcry_pkey_handle {
+ int algo;
+ unsigned int flags;
+
+ union {
+ struct pkey_ecc ecc;
+ struct pkey_rsa rsa;
+ };
+};
diff --git a/cipher/pkey-rsapss.c b/cipher/pkey-rsapss.c
new file mode 100644
index 00000000..2e408753
--- /dev/null
+++ b/cipher/pkey-rsapss.c
@@ -0,0 +1,202 @@
+/* pkey-rsapss.c - PKEY API implementation for RSA-PSS
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see .
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "g10lib.h"
+#include "gcrypt-int.h"
+#include "pkey-internal.h"
+
+gcry_error_t
+_gcry_pkey_rsapss_sign (gcry_pkey_hd_t h,
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[],
+ int num_out, unsigned char *out[], size_t out_len[])
+{
+ gcry_error_t err = 0;
+ gcry_sexp_t s_sk = NULL;
+ gcry_sexp_t s_msg= NULL;
+ gcry_sexp_t s_sig= NULL;
+ const char *md_name;
+ gcry_sexp_t s_tmp, s_tmp2;
+
+ if (num_in != 2)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ if (num_out != 1)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ switch (h->rsa.md_algo)
+ {
+ case GCRY_MD_SHA224:
+ md_name = "sha224";
+ break;
+ case GCRY_MD_SHA256:
+ md_name = "sha256";
+ break;
+ case GCRY_MD_SHA384:
+ md_name = "sha384";
+ break;
+ case GCRY_MD_SHA512:
+ md_name = "sha512";
+ break;
+ default:
+ return gpg_error (GPG_ERR_INV_ARG);
+ }
+
+ err = sexp_build (&s_sk, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)h->rsa.n_len, h->rsa.n,
+ (int)h->rsa.e_len, h->rsa.e,
+ (int)h->rsa.d_len, h->rsa.d);
+ if (err)
+ return err;
+
+ err = sexp_build (&s_msg, NULL,
+ "(data"
+ " (flags pss)"
+ " (hash-algo %s)"
+ " (value %b)"
+ " (salt-length %d)"
+ " (random-override %b))",
+ md_name,
+ (int)in_len[0], in[0],
+ (int)in_len[1],
+ (int)in_len[1], in[1]);
+ if (err)
+ {
+ sexp_release (s_sk);
+ return err;
+ }
+
+ err = _gcry_pk_sign (&s_sig, s_msg, s_sk);
+ sexp_release (s_sk);
+ sexp_release (s_msg);
+ if (err)
+ return err;
+
+ out[0] = NULL;
+ s_tmp2 = NULL;
+ s_tmp = sexp_find_token (s_sig, "sig-val", 0);
+ if (s_tmp)
+ {
+ s_tmp2 = s_tmp;
+ s_tmp = sexp_find_token (s_tmp2, "rsa", 0);
+ if (s_tmp)
+ {
+ sexp_release (s_tmp2);
+ s_tmp2 = s_tmp;
+ s_tmp = sexp_find_token (s_tmp2, "s", 0);
+ if (s_tmp)
+ {
+ out[0] = sexp_nth_buffer (s_tmp, 1, &out_len[0]);
+ sexp_release (s_tmp);
+ }
+ }
+ }
+ sexp_release (s_tmp2);
+
+ if (out[0] == NULL)
+ err = gpg_error (GPG_ERR_BAD_SIGNATURE);
+
+ sexp_release (s_sig);
+
+ return err;
+}
+
+gcry_error_t
+_gcry_pkey_rsapss_verify (gcry_pkey_hd_t h,
+ int num_in, const unsigned char *const in[],
+ const size_t in_len[])
+{
+ gcry_error_t err = 0;
+ gcry_sexp_t s_pk = NULL;
+ const char *md_name;
+ gcry_sexp_t s_msg= NULL;
+ gcry_sexp_t s_sig= NULL;
+
+ if (num_in != 3)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ switch (h->rsa.md_algo)
+ {
+ case GCRY_MD_SHA224:
+ md_name = "sha224";
+ break;
+ case GCRY_MD_SHA256:
+ md_name = "sha256";
+ break;
+ case GCRY_MD_SHA384:
+ md_name = "sha384";
+ break;
+ case GCRY_MD_SHA512:
+ md_name = "sha512";
+ break;
+ default:
+ return gpg_error (GPG_ERR_INV_ARG);
+ }
+
+ err = sexp_build (&s_pk, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)h->rsa.n_len, h->rsa.n,
+ (int)h->rsa.e_len, h->rsa.e);
+ if (err)
+ return err;
+
+ err = sexp_build (&s_msg, NULL,
+ "(data"
+ " (flags pss)"
+ " (hash-algo %s)"
+ " (value %b)"
+ " (salt-length %d)"
+ " (random-override %b))",
+ md_name,
+ (int)in_len[0], in[0],
+ (int)in_len[1],
+ (int)in_len[1], in[1]);
+ if (err)
+ {
+ sexp_release (s_pk);
+ return err;
+ }
+
+ err = sexp_build (&s_sig, NULL,
+ "(sig-val(rsa(s %b)))",
+ (int)in_len[2], in[2]);
+ if (err)
+ {
+ sexp_release (s_msg);
+ sexp_release (s_pk);
+ return err;
+ }
+
+ err = _gcry_pk_verify (s_sig, s_msg, s_pk);
+
+ sexp_release (s_sig);
+ sexp_release (s_msg);
+ sexp_release (s_pk);
+
+ return err;
+}
diff --git a/cipher/pkey.c b/cipher/pkey.c
index 3f06e507..fb230eb8 100644
--- a/cipher/pkey.c
+++ b/cipher/pkey.c
@@ -1,211 +1,318 @@
/* pkey.c - pubric key cryptography API
* Copyright (C) 2021 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
#include
#include
#include
#include
#include
#include
#include "g10lib.h"
#include "gcrypt-int.h"
#include "pkey-internal.h"
gcry_error_t
_gcry_pkey_vopen (gcry_pkey_hd_t *h_p, int algo, unsigned int flags,
va_list arg_ptr)
{
gcry_error_t err = 0;
gcry_pkey_hd_t h;
- int curve;
- unsigned char *pk;
- unsigned char *sk;
if (algo == GCRY_PKEY_ECC)
;
else if (algo == GCRY_PKEY_RSA)
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ ;
else if (algo == GCRY_PKEY_DSA)
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
else if (algo == GCRY_PKEY_ELG)
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
else
err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
if (err)
return err;
if (!(h = xtrycalloc (1, sizeof (struct gcry_pkey_handle))))
return gpg_err_code_from_syserror ();
h->algo = algo;
h->flags = flags;
- /* For now, it's GCRY_PKEY_ECC only. */
- curve = va_arg (arg_ptr, int);
- if (curve == GCRY_PKEY_CURVE_ED25519)
- ;
- else if (curve == GCRY_PKEY_CURVE_ED448)
- ;
- else
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- if (err)
+ if (algo == GCRY_PKEY_ECC)
{
- xfree (h);
- return err;
- }
+ int curve;
+ unsigned char *pk;
+ unsigned char *sk;
- h->curve = curve;
-
- *h_p = h;
+ curve = va_arg (arg_ptr, int);
+ if (curve == GCRY_PKEY_CURVE_ED25519)
+ ;
+ else if (curve == GCRY_PKEY_CURVE_ED448)
+ ;
+ else
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ if (err)
+ {
+ xfree (h);
+ return err;
+ }
- if (!(flags & GCRY_PKEY_FLAG_SECRET))
- {
- pk = va_arg (arg_ptr, unsigned char *);
- h->pk_len = va_arg (arg_ptr, size_t);
- h->sk = sk = NULL;
- h->sk_len = 0;
- }
- else
- {
- pk = va_arg (arg_ptr, unsigned char *);
- h->pk_len = va_arg (arg_ptr, size_t);
- sk = va_arg (arg_ptr, unsigned char *);
- h->sk_len = va_arg (arg_ptr, size_t);
- }
+ h->ecc.curve = curve;
- if (err)
- {
- xfree (h);
- return err;
- }
+ if (!(flags & GCRY_PKEY_FLAG_SECRET))
+ {
+ pk = va_arg (arg_ptr, unsigned char *);
+ h->ecc.pk_len = va_arg (arg_ptr, size_t);
+ h->ecc.sk = sk = NULL;
+ h->ecc.sk_len = 0;
+ }
+ else
+ {
+ pk = va_arg (arg_ptr, unsigned char *);
+ h->ecc.pk_len = va_arg (arg_ptr, size_t);
+ sk = va_arg (arg_ptr, unsigned char *);
+ h->ecc.sk_len = va_arg (arg_ptr, size_t);
+ }
- if (pk)
- {
- h->pk = xtrymalloc (h->pk_len);
- if (!h->pk)
+ if (err)
{
- err = gpg_err_code_from_syserror ();
xfree (h);
return err;
}
- memcpy (h->pk, pk, h->pk_len);
- }
- else
- h->pk = NULL;
- if (sk)
+ if (pk)
+ {
+ h->ecc.pk = xtrymalloc (h->ecc.pk_len);
+ if (!h->ecc.pk)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (h);
+ return err;
+ }
+ memcpy (h->ecc.pk, pk, h->ecc.pk_len);
+ }
+ else
+ h->ecc.pk = NULL;
+
+ if (sk)
+ {
+ h->ecc.sk = xtrymalloc_secure (h->ecc.sk_len);
+ if (!h->ecc.sk)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (h->ecc.pk);
+ xfree (h);
+ return err;
+ }
+ memcpy (h->ecc.sk, sk, h->ecc.sk_len);
+ }
+ }
+ else if (algo == GCRY_PKEY_RSA)
{
- h->sk = xtrymalloc_secure (h->sk_len);
- if (!h->sk)
+ int scheme;
+ int md_algo;
+ unsigned char *n;
+ unsigned char *e;
+ unsigned char *d;
+
+ scheme = va_arg (arg_ptr, int);
+ h->rsa.scheme = scheme;
+
+ md_algo = va_arg (arg_ptr, int);
+ h->rsa.md_algo = md_algo;
+
+ if (!(flags & GCRY_PKEY_FLAG_SECRET))
+ {
+ n = va_arg (arg_ptr, unsigned char *);
+ h->rsa.n_len = va_arg (arg_ptr, size_t);
+ e = va_arg (arg_ptr, unsigned char *);
+ h->rsa.e_len = va_arg (arg_ptr, size_t);
+ h->rsa.d = d = NULL;
+ h->rsa.d_len = 0;
+ }
+ else
+ {
+ n = va_arg (arg_ptr, unsigned char *);
+ h->rsa.n_len = va_arg (arg_ptr, size_t);
+ e = va_arg (arg_ptr, unsigned char *);
+ h->rsa.e_len = va_arg (arg_ptr, size_t);
+ d = va_arg (arg_ptr, unsigned char *);
+ h->rsa.d_len = va_arg (arg_ptr, size_t);
+ }
+
+ if (err)
{
- err = gpg_err_code_from_syserror ();
- xfree (h->pk);
xfree (h);
return err;
}
- memcpy (h->sk, sk, h->sk_len);
+
+ if (n)
+ {
+ h->rsa.n = xtrymalloc (h->rsa.n_len);
+ if (!h->rsa.n)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (h);
+ return err;
+ }
+ memcpy (h->rsa.n, n, h->rsa.n_len);
+ }
+ else
+ h->rsa.n = NULL;
+
+ if (e)
+ {
+ h->rsa.e = xtrymalloc (h->rsa.e_len);
+ if (!h->rsa.e)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (h);
+ return err;
+ }
+ memcpy (h->rsa.e, e, h->rsa.e_len);
+ }
+ else
+ h->rsa.e = NULL;
+
+ if (d)
+ {
+ h->rsa.d = xtrymalloc (h->rsa.d_len);
+ if (!h->rsa.d)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (h);
+ return err;
+ }
+ memcpy (h->rsa.d, d, h->rsa.d_len);
+ }
}
+ *h_p = h;
+
return err;
}
gcry_error_t
_gcry_pkey_ctl (gcry_pkey_hd_t h, int cmd, void *buffer, size_t buflen)
{
gcry_error_t err = 0;
(void)h; (void)cmd; (void)buffer; (void)buflen;
/* FIXME: Not yet implemented anything. */
return err;
}
/* For now, it uses SEXP implementation, because the purpose is
to test the API (but not the implementation).
Will be rewritten soon.
Currently, it's like:
[ gcry_pkey_op API (with binary data) ]
|
[ gcry_pk_ API (with SEXP) ]
|
[ lower level public key implementations (with SEXP) ]
It will be like:
[ gcry_pk_ API with SEXP ] [ gcry_pkey_op API with binary data ]
| |
[ lower level public key implementations ]
That is, lower level public key implementations won't have any
(direct) handling of SEXP.
*/
gcry_error_t
_gcry_pkey_op (gcry_pkey_hd_t h, int cmd,
int num_in, const unsigned char *const in[],
const size_t in_len[],
int num_out, unsigned char *out[], size_t out_len[])
{
gcry_error_t err = 0;
/* Just for Ed25519 and Ed448 for now. Will support more... */
if (h->algo == GCRY_PKEY_ECC)
{
- if (h->curve == GCRY_PKEY_CURVE_ED25519)
+ if (h->ecc.curve == GCRY_PKEY_CURVE_ED25519)
{
if (cmd == GCRY_PKEY_OP_SIGN)
err = _gcry_pkey_ed25519_sign (h, num_in, in, in_len,
num_out, out, out_len);
else if (cmd == GCRY_PKEY_OP_VERIFY)
err = _gcry_pkey_ed25519_verify (h, num_in, in, in_len);
else
err = gpg_error (GPG_ERR_INV_OP);
}
- else if (h->curve == GCRY_PKEY_CURVE_ED448)
+ else if (h->ecc.curve == GCRY_PKEY_CURVE_ED448)
{
if (cmd == GCRY_PKEY_OP_SIGN)
err = _gcry_pkey_ed448_sign (h, num_in, in, in_len,
num_out, out, out_len);
else if (cmd == GCRY_PKEY_OP_VERIFY)
err = _gcry_pkey_ed448_verify (h, num_in, in, in_len);
else
err = gpg_error (GPG_ERR_INV_OP);
}
else
err = gpg_error (GPG_ERR_INV_OP);
}
+ else if (h->algo == GCRY_PKEY_RSA)
+ {
+ if (h->rsa.scheme == GCRY_PKEY_RSA_PSS)
+ {
+ if (cmd == GCRY_PKEY_OP_SIGN)
+ err = _gcry_pkey_rsapss_sign (h, num_in, in, in_len,
+ num_out, out, out_len);
+ else if (cmd == GCRY_PKEY_OP_VERIFY)
+ err = _gcry_pkey_rsapss_verify (h, num_in, in, in_len);
+ else
+ err = gpg_error (GPG_ERR_INV_OP);
+ }
+ else
+ err = gpg_error (GPG_ERR_INV_OP);
+ }
else
err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
return err;
}
void
_gcry_pkey_close (gcry_pkey_hd_t h)
{
if (h)
{
- xfree (h->sk);
- xfree (h->pk);
+ if (h->algo == GCRY_PKEY_ECC)
+ {
+ xfree (h->ecc.pk);
+ xfree (h->ecc.sk);
+ }
+ else if (h->algo == GCRY_PKEY_RSA)
+ {
+ xfree (h->rsa.n);
+ xfree (h->rsa.e);
+ xfree (h->rsa.d);
+ }
+
xfree (h);
}
}