From: Daiki Ueno <dueno(a)redhat.com>
Signed-off-by: Daiki Ueno <dueno(a)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);
+}
--
2.9.3
Hi,
I coded a high performance sha256 algorithm for ppc64le:
https://git.lysator.liu.se/gut/nettle/commit/a8facb03a69787a93c91b426f32a0b…
Tests were performed with different files and comparing it against the original C implementation by using the Ubuntu's 16.10 libnettle.so.6 by using the following code:
https://gist.github.com/gut/9622d4535a9e3f9ea3b0ded2762d4b28
The results I got by using an ubuntu-16.10 iso as an input (around 700mb):
$ time ./sha256-test ~/ubuntu-16.10-server-ppc64el.iso
d14bdb413ea6cdc8d9354fcbc37a834b7de0c23f992deb0c6764d0fd5d65408e
real 0m14.607s
user 0m13.988s
sys 0m0.616s
$ export LD_LIBRARY_PATH=~/nettle # link with user and not system lib
$ time ./sha256-test ~/ubuntu-16.10-server-ppc64el.iso
d14bdb413ea6cdc8d9354fcbc37a834b7de0c23f992deb0c6764d0fd5d65408e
real 0m2.242s
user 0m2.052s
sys 0m0.188s
I also plan on doing the sha512 if I'm heading to the right direction.
Regards,
Gustavo Serra Scalet
> -----Original Message-----
> From: Nikos Mavrogiannopoulos [mailto:n.mavrogiannopoulos@gmail.com]
> Sent: terça-feira, 28 de fevereiro de 2017 06:07
> To: Niels Möller <nisse(a)lysator.liu.se>
> Cc: Gustavo Serra Scalet <gustavo.scalet(a)eldorado.org.br>; nettle-
> bugs(a)lists.lysator.liu.se
> Subject: Re: Is the gitlab being used or not?
>
> On Tue, Feb 28, 2017 at 7:48 AM, Niels Möller <nisse(a)lysator.liu.se>
> wrote:
> > Gustavo Serra Scalet <gustavo.scalet(a)eldorado.org.br> writes:
> >
> >> I noticed there is no merging/update activities on the gitlab
> website:
> >> https://git.lysator.liu.se/nettle/nettle/merge_requests?scope=all&sta
> >> te=all
> >>
> >> I wonder if it's used.
> >
> > It's used mainly for the plain git hosting. I rarely use the more
> > advance features, and almost never access the web interface.
>
> Would it be possible to disable then the merge request option in the
> gitlab interface? There are already 5 patches there.
>
> Most likely you need to go to -> Edit project and disable the issue
> tracker and the merge commits for everyone (at least that's the process
> in the new gitlab).
>
> >> The reason for asking is that I'm willing to integrate a
> >> ppc64le-specific implementation using SIMD registers for the SHA-2
> >> algorithm so I would create an Issue to discuss it and then
> >> submitting the code as a Merge Request. But only if that's the way
> >> for upstreaming code on nettle. If not, please advise if this list
> >> can be used.
> >
> > Discussion should take place on this list. You can mail patches here,
> > or create a merge request on gitlab. But in the latter case, please
> > send a note here too, otherwise it might be overlooked.
>
> I attach a patch to document that process. I use CONTRIBUTION.md show it
> shows prominently on the gitlab interfaces.
>
> regards,
> Nikos
Hi,
I noticed there is no merging/update activities on the gitlab website:
https://git.lysator.liu.se/nettle/nettle/merge_requests?scope=all&state=all
I wonder if it's used.
The reason for asking is that I'm willing to integrate a ppc64le-specific implementation using SIMD registers for the SHA-2 algorithm so I would create an Issue to discuss it and then submitting the code as a Merge Request. But only if that's the way for upstreaming code on nettle. If not, please advise if this list can be used.
Sorry for using the "nettle-bugs" mailing list, which is not a discussion mailing list.
Cheers,
Gustavo Serra Scalet