From: Daiki Ueno dueno@redhat.com
Signed-off-by: Daiki Ueno dueno@redhat.com --- There was an obvious buffer overrun in mgf1-test.c, which should be fixed in this version. --- Makefile.in | 5 +- mgf1-sha256.c | 47 +++++++++++ mgf1-sha384.c | 47 +++++++++++ mgf1-sha512.c | 47 +++++++++++ mgf1.c | 72 +++++++++++++++++ mgf1.h | 70 ++++++++++++++++ nettle-types.h | 3 + pss-sha256.c | 64 +++++++++++++++ pss-sha512.c | 90 +++++++++++++++++++++ pss.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ pss.h | 105 ++++++++++++++++++++++++ testsuite/.test-rules.make | 6 ++ testsuite/Makefile.in | 4 +- testsuite/mgf1-test.c | 23 ++++++ testsuite/pss-test.c | 35 ++++++++ 15 files changed, 810 insertions(+), 3 deletions(-) create mode 100644 mgf1-sha256.c create mode 100644 mgf1-sha384.c create mode 100644 mgf1-sha512.c create mode 100644 mgf1.c create mode 100644 mgf1.h create mode 100644 pss-sha256.c create mode 100644 pss-sha512.c create mode 100644 pss.c create mode 100644 pss.h create mode 100644 testsuite/mgf1-test.c create mode 100644 testsuite/pss-test.c
diff --git a/Makefile.in b/Makefile.in index 135542f..035074c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -110,6 +110,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ md2.c md2-meta.c md4.c md4-meta.c \ md5.c md5-compress.c md5-compat.c md5-meta.c \ memeql-sec.c memxor.c memxor3.c \ + mgf1.c mgf1-sha256.c mgf1-sha384.c mgf1-sha512.c \ nettle-meta-aeads.c nettle-meta-armors.c \ nettle-meta-ciphers.c nettle-meta-hashes.c \ pbkdf2.c pbkdf2-hmac-sha1.c pbkdf2-hmac-sha256.c \ @@ -144,6 +145,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ pkcs1.c pkcs1-encrypt.c pkcs1-decrypt.c \ pkcs1-rsa-digest.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \ pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \ + pss.c pss-sha256.c pss-sha512.c \ rsa.c rsa-sign.c rsa-sign-tr.c rsa-verify.c \ rsa-pkcs1-sign.c rsa-pkcs1-sign-tr.c rsa-pkcs1-verify.c \ rsa-md5-sign.c rsa-md5-sign-tr.c rsa-md5-verify.c \ @@ -194,9 +196,10 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ md2.h md4.h \ md5.h md5-compat.h \ memops.h memxor.h \ + mgf1.h \ nettle-meta.h nettle-types.h \ pbkdf2.h \ - pgp.h pkcs1.h realloc.h ripemd160.h rsa.h \ + pgp.h pkcs1.h pss.h realloc.h ripemd160.h rsa.h \ salsa20.h sexp.h \ serpent.h sha.h sha1.h sha2.h sha3.h twofish.h \ umac.h yarrow.h poly1305.h diff --git a/mgf1-sha256.c b/mgf1-sha256.c new file mode 100644 index 0000000..11e908c --- /dev/null +++ b/mgf1-sha256.c @@ -0,0 +1,47 @@ +/* mgf1-sha256.c + + PKCS#1 mask generation function 1, based on SHA-256. + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mgf1.h" + +#include "nettle-meta.h" + +int +mgf1_sha256(const struct sha256_ctx *hash, size_t mask_length, uint8_t *mask) +{ + struct sha256_ctx state; + return mgf1(hash, &state, &nettle_sha256, mask_length, mask); +} diff --git a/mgf1-sha384.c b/mgf1-sha384.c new file mode 100644 index 0000000..5dd2b07 --- /dev/null +++ b/mgf1-sha384.c @@ -0,0 +1,47 @@ +/* mgf1-sha384.c + + PKCS#1 mask generation function 1, based on SHA-384. + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mgf1.h" + +#include "nettle-meta.h" + +int +mgf1_sha384(const struct sha384_ctx *hash, size_t mask_length, uint8_t *mask) +{ + struct sha384_ctx state; + return mgf1(hash, &state, &nettle_sha384, mask_length, mask); +} diff --git a/mgf1-sha512.c b/mgf1-sha512.c new file mode 100644 index 0000000..d1fba5f --- /dev/null +++ b/mgf1-sha512.c @@ -0,0 +1,47 @@ +/* mgf1-sha512.c + + PKCS#1 mask generation function 1, based on SHA-512. + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mgf1.h" + +#include "nettle-meta.h" + +int +mgf1_sha512(const struct sha512_ctx *hash, size_t mask_length, uint8_t *mask) +{ + struct sha512_ctx state; + return mgf1(hash, &state, &nettle_sha512, mask_length, mask); +} diff --git a/mgf1.c b/mgf1.c new file mode 100644 index 0000000..a96b086 --- /dev/null +++ b/mgf1.c @@ -0,0 +1,72 @@ +/* mgf1.c + + PKCS#1 mask generation function 1 (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mgf1.h" + +#include <assert.h> +#include <string.h> + +#include "nettle-internal.h" + +#define MGF1_MIN(a,b) ((a) < (b) ? (a) : (b)) + +int +mgf1(void *seed, void *state, const struct nettle_hash *hash, + size_t mask_length, uint8_t *mask) +{ + TMP_DECL(h, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + size_t i, blocks; + uint8_t c[4], *p; + + TMP_ALLOC(h, hash->digest_size); + + blocks = (mask_length + hash->digest_size - 1) / hash->digest_size; + for (i = 0, p = mask; i < blocks; i++, p += hash->digest_size) + { + c[0] = (i >> 24) & 0xFF; + c[1] = (i >> 16) & 0xFF; + c[2] = (i >> 8) & 0xFF; + c[3] = i & 0xFF; + + memcpy(state, seed, hash->context_size); + hash->update(state, 4, c); + hash->digest(state, hash->digest_size, h); + memcpy(p, h, MGF1_MIN(hash->digest_size, mask_length - (p - mask))); + } + + return 1; +} diff --git a/mgf1.h b/mgf1.h new file mode 100644 index 0000000..bbaffce --- /dev/null +++ b/mgf1.h @@ -0,0 +1,70 @@ +/* mgf1.h + + PKCS#1 mask generation function 1 (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_MGF1_H_INCLUDED +#define NETTLE_MGF1_H_INCLUDED + +#include "nettle-meta.h" + +#include "sha1.h" +#include "sha2.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Namespace mangling */ +#define mgf1 nettle_mgf1 +#define mgf1_sha256 nettle_mgf1_sha256 +#define mgf1_sha384 nettle_mgf1_sha384 +#define mgf1_sha512 nettle_mgf1_sha512 + +int +mgf1(void *seed, void *state, const struct nettle_hash *hash, + size_t mask_length, uint8_t *mask); + +int +mgf1_sha256(const struct sha256_ctx *hash, size_t mask_length, uint8_t *mask); + +int +mgf1_sha384(const struct sha384_ctx *hash, size_t mask_length, uint8_t *mask); + +int +mgf1_sha512(const struct sha512_ctx *hash, size_t mask_length, uint8_t *mask); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MGF1_H_INCLUDED */ diff --git a/nettle-types.h b/nettle-types.h index 475937d..b687958 100644 --- a/nettle-types.h +++ b/nettle-types.h @@ -103,6 +103,9 @@ typedef int nettle_armor_decode_update_func(void *ctx,
typedef int nettle_armor_decode_final_func(void *ctx);
+typedef int nettle_mgf_func(void *ctx, size_t mask_length, uint8_t *mask); + + #ifdef __cplusplus } #endif diff --git a/pss-sha256.c b/pss-sha256.c new file mode 100644 index 0000000..9c12037 --- /dev/null +++ b/pss-sha256.c @@ -0,0 +1,64 @@ +/* pss.c + + PKCS#1 RSA-PSS padding, using SHA-256 (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "pss.h" + +int +pss_sha256_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest) +{ + struct sha256_ctx state; + return pss_encode(m, bits, + &state, &nettle_sha256, + (nettle_mgf_func *) mgf1_sha256, + salt_length, salt, + digest); +} + +int +pss_sha256_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest) +{ + struct sha256_ctx state; + return pss_verify(m, bits, + &state, &nettle_sha256, + (nettle_mgf_func *) mgf1_sha256, + salt_length, + digest); +} diff --git a/pss-sha512.c b/pss-sha512.c new file mode 100644 index 0000000..e24b45d --- /dev/null +++ b/pss-sha512.c @@ -0,0 +1,90 @@ +/* pss.c + + PKCS#1 RSA-PSS padding, using SHA-384 and SHA-512 (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "pss.h" + +int +pss_sha384_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest) +{ + struct sha384_ctx state; + return pss_encode(m, bits, + &state, &nettle_sha384, + (nettle_mgf_func *) mgf1_sha384, + salt_length, salt, + digest); +} + +int +pss_sha384_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest) +{ + struct sha384_ctx state; + return pss_verify(m, bits, + &state, &nettle_sha384, + (nettle_mgf_func *) mgf1_sha384, + salt_length, + digest); +} + +int +pss_sha512_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest) +{ + struct sha512_ctx state; + return pss_encode(m, bits, + &state, &nettle_sha512, + (nettle_mgf_func *) mgf1_sha512, + salt_length, salt, + digest); +} + +int +pss_sha512_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest) +{ + struct sha512_ctx state; + return pss_verify(m, bits, + &state, &nettle_sha512, + (nettle_mgf_func *) mgf1_sha512, + salt_length, + digest); +} diff --git a/pss.c b/pss.c new file mode 100644 index 0000000..5dd23a7 --- /dev/null +++ b/pss.c @@ -0,0 +1,195 @@ +/* pss.c + + PKCS#1 RSA-PSS padding (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "pss.h" + +#include "bignum.h" +#include "gmp-glue.h" + +#include "memxor.h" +#include "nettle-internal.h" + +static const uint8_t pss_masks[8] = { + 0xFF, 0x7F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x1 +}; + +int +pss_encode(mpz_t m, size_t bits, + void *state, const struct nettle_hash *hash, + nettle_mgf_func mgf, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest) +{ + TMP_GMP_DECL(em, uint8_t); + uint8_t pad[8]; + size_t key_size = (bits + 7) / 8; + size_t j; + + TMP_GMP_ALLOC(em, key_size); + + if (key_size < hash->digest_size + salt_length + 2) + { + TMP_GMP_FREE(em); + return 0; + } + + /* Compute M'. */ + hash->init(state); + memset(pad, 0, 8); + hash->update(state, 8, pad); + hash->update(state, hash->digest_size, digest); + hash->update(state, salt_length, salt); + + /* Store H in EM, right after maskedDB. */ + hash->digest(state, hash->digest_size, em + key_size - hash->digest_size - 1); + + /* Compute dbMask. */ + hash->init(state); + hash->update(state, hash->digest_size, em + key_size - hash->digest_size - 1); + + mgf(state, key_size - hash->digest_size - 1, em); + + /* Compute maskedDB and store it in front of H in EM. */ + for (j = 0; j < key_size - salt_length - hash->digest_size - 2; j++) + em[j] ^= 0; + em[j++] ^= 1; + memxor(em + j, salt, salt_length); + j += salt_length; + + /* Store the trailer field following H. */ + j += hash->digest_size; + *(em + j) = 0xbc; + + /* Clear the leftmost 8 * emLen - emBits of the leftmost octet in EM. */ + *em &= pss_masks[(8 * key_size - bits)]; + + nettle_mpz_set_str_256_u(m, key_size, em); + TMP_GMP_FREE(em); + return 1; +} + +int +pss_verify(mpz_t m, size_t bits, + void *state, const struct nettle_hash *hash, + nettle_mgf_func mgf, + size_t salt_length, + const uint8_t *digest) +{ + TMP_GMP_DECL(em, uint8_t); + TMP_DECL(h2, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + uint8_t pad[8], *h, *db, *salt; + size_t key_size = (bits + 7) / 8; + size_t j; + + /* Allocate twice the key size to store the intermediate data DB + * following the EM value. */ + TMP_GMP_ALLOC(em, key_size * 2); + + TMP_ALLOC(h2, hash->digest_size); + + if (key_size < hash->digest_size + salt_length + 2) + { + TMP_GMP_FREE(em); + return 0; + } + + nettle_mpz_get_str_256(key_size, em, m); + + /* Check the trailer field. */ + if (em[key_size - 1] != 0xbc) + { + TMP_GMP_FREE(em); + return 0; + } + + /* Extract H. */ + h = em + (key_size - hash->digest_size - 1); + + /* Check if the leftmost 8 * emLen - emBits bits of the leftmost + * octet of EM are all equal to zero. */ + if ((*em & ~pss_masks[(8 * key_size - bits)]) != 0) + { + TMP_GMP_FREE(em); + return 0; + } + + /* Compute dbMask. */ + hash->init(state); + hash->update(state, hash->digest_size, h); + + db = em + key_size; + mgf(state, key_size - hash->digest_size - 1, db); + + /* Compute DB. */ + memxor(db, em, key_size - hash->digest_size - 1); + + *db &= pss_masks[(8 * key_size - bits)]; + for (j = 0; j < key_size - salt_length - hash->digest_size - 2; j++) + if (db[j] != 0) { + TMP_GMP_FREE(em); + return 0; + } + + /* Check the octet right after PS is 0x1. */ + if (db[j] != 0x1) + { + TMP_GMP_FREE(em); + return 0; + } + salt = db + j + 1; + + /* Compute H'. */ + memset(pad, 0, 8); + hash->init(state); + hash->update(state, 8, pad); + hash->update(state, hash->digest_size, digest); + hash->update(state, salt_length, salt); + hash->digest(state, hash->digest_size, h2); + + /* Check if H' = H. */ + if (memcmp(h2, h, hash->digest_size) != 0) + { + TMP_GMP_FREE(em); + return 0; + } + + TMP_GMP_FREE(em); + return 1; +} diff --git a/pss.h b/pss.h new file mode 100644 index 0000000..1ebe1eb --- /dev/null +++ b/pss.h @@ -0,0 +1,105 @@ +/* pss.h + + PKCS#1 RSA-PSS (RFC-3447). + + Copyright (C) 2017 Daiki Ueno + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it 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. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_PSS_H_INCLUDED +#define NETTLE_PSS_H_INCLUDED + +#include "nettle-types.h" +#include "bignum.h" + +#include "mgf1.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Namespace mangling */ +#define pss_encode nettle_pss_encode +#define pss_verify nettle_pss_verify +#define pss_sha256_encode nettle_pss_sha256_encode +#define pss_sha256_verify nettle_pss_sha256_verify +#define pss_sha384_encode nettle_pss_sha384_encode +#define pss_sha384_verify nettle_pss_sha384_verify +#define pss_sha512_encode nettle_pss_sha512_encode +#define pss_sha512_verify nettle_pss_sha512_verify + +int +pss_encode(mpz_t m, size_t bits, + void *state, const struct nettle_hash *hash, + nettle_mgf_func mgf, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest); + +int +pss_verify(mpz_t m, size_t bits, + void *state, const struct nettle_hash *hash, + nettle_mgf_func mgf, + size_t salt_length, + const uint8_t *digest); + +int +pss_sha256_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest); + +int +pss_sha256_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest); + +int +pss_sha384_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest); + +int +pss_sha384_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest); + +int +pss_sha512_encode(mpz_t m, size_t bits, + size_t salt_length, const uint8_t *salt, + const uint8_t *digest); + +int +pss_sha512_verify(mpz_t m, size_t bits, + size_t salt_length, + const uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_PSS_H_INCLUDED */ diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index b263e1f..2b4499f 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -157,6 +157,9 @@ yarrow-test$(EXEEXT): yarrow-test.$(OBJEXT) pbkdf2-test$(EXEEXT): pbkdf2-test.$(OBJEXT) $(LINK) pbkdf2-test.$(OBJEXT) $(TEST_OBJS) -o pbkdf2-test$(EXEEXT)
+mgf1-test$(EXEEXT): mgf1-test.$(OBJEXT) + $(LINK) mgf1-test.$(OBJEXT) $(TEST_OBJS) -o mgf1-test$(EXEEXT) + sexp-test$(EXEEXT): sexp-test.$(OBJEXT) $(LINK) sexp-test.$(OBJEXT) $(TEST_OBJS) -o sexp-test$(EXEEXT)
@@ -178,6 +181,9 @@ random-prime-test$(EXEEXT): random-prime-test.$(OBJEXT) pkcs1-test$(EXEEXT): pkcs1-test.$(OBJEXT) $(LINK) pkcs1-test.$(OBJEXT) $(TEST_OBJS) -o pkcs1-test$(EXEEXT)
+pss-test$(EXEEXT): pss-test.$(OBJEXT) + $(LINK) pss-test.$(OBJEXT) $(TEST_OBJS) -o pss-test$(EXEEXT) + rsa-sign-tr-test$(EXEEXT): rsa-sign-tr-test.$(OBJEXT) $(LINK) rsa-sign-tr-test.$(OBJEXT) $(TEST_OBJS) -o rsa-sign-tr-test$(EXEEXT)
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 689d432..4a9604f 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -30,12 +30,12 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \ hmac-test.c umac-test.c \ meta-hash-test.c meta-cipher-test.c\ meta-aead-test.c meta-armor-test.c \ - buffer-test.c yarrow-test.c pbkdf2-test.c + buffer-test.c yarrow-test.c pbkdf2-test.c mgf1-test.c
TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ rsa2sexp-test.c sexp2rsa-test.c \ bignum-test.c random-prime-test.c \ - pkcs1-test.c rsa-sign-tr-test.c \ + pkcs1-test.c pss-test.c rsa-sign-tr-test.c \ rsa-test.c rsa-encrypt-test.c rsa-keygen-test.c \ dsa-test.c dsa-keygen-test.c \ curve25519-dh-test.c \ diff --git a/testsuite/mgf1-test.c b/testsuite/mgf1-test.c new file mode 100644 index 0000000..967be07 --- /dev/null +++ b/testsuite/mgf1-test.c @@ -0,0 +1,23 @@ +#include "testutils.h" +#include "mgf1.h" + +void +test_main(void) +{ + struct sha256_ctx hash; + struct tstring *expected; + uint8_t mask[120]; + int ret; + + expected = SHEX("cf2db1ac9867debdf8ce91f99f141e5544bf26ca36b3fd4f8e4035" + "eec42cab0d46c386ebccef82ba0bb0b095aaa5548b03cdff695187" + "1c6fb505af68af688332f885d324a47d2145a3d8392c37978d7dc9" + "84c95728950c4cf3de6becc59e60ea506951bd40e6de3863095064" + "3ab2edbb47dc66cb54beb2d1"); + + sha256_init(&hash); + sha256_update(&hash, 3, "abc"); + ret = mgf1_sha256(&hash, 120, mask); + ASSERT(ret == 1); + ASSERT(MEMEQ (120, mask, expected->data)); +} diff --git a/testsuite/pss-test.c b/testsuite/pss-test.c new file mode 100644 index 0000000..2d53e03 --- /dev/null +++ b/testsuite/pss-test.c @@ -0,0 +1,35 @@ +#include "testutils.h" + +#include "pss.h" + +void +test_main(void) +{ + struct tstring *salt; + struct tstring *digest; + mpz_t m; + mpz_t expected; + int ret; + + mpz_init(m); + mpz_init(expected); + + salt = SHEX("11223344556677889900"); + /* From sha256-test.c */ + digest = SHEX("ba7816bf8f01cfea 414140de5dae2223" + "b00361a396177a9c b410ff61f20015ad"); + ret = pss_sha256_encode(m, 1024, salt->length, salt->data, digest->data); + ASSERT(ret == 1); + + mpz_set_str(expected, + "76b9a52705c8382c5367732f993184eff340b6305c9f73e7e308c8" + "004fcc15cbbaab01e976bae4b774628595379a2d448a36b3ea6fa8" + "353b97eeea7bdac93b4b7807ac98cd4b3bebfb31f3718e1dd3625f" + "227fbb8696606498e7070e21c3cbbd7386ea20eb81ac7927e0c6d1" + "d7788826a63af767f301bcc05dd65b00da862cbc", 16); + + ASSERT(mpz_cmp(m, expected) == 0); + + ret = pss_sha256_verify(m, 1024, salt->length, digest->data); + ASSERT(ret == 1); +}