summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2016-01-10 11:34:46 +0100
committerNiels Möller <nisse@lysator.liu.se>2016-01-10 11:34:46 +0100
commit4ebc67a7a29748bcdd3983e8e75e0b0c770b3515 (patch)
tree0b532a4c6cca16f909e3b9c28430ca1c064f7c38
parentd78467e14f59293b3a9e2df212613114ec4abd16 (diff)
downloadnettle-4ebc67a7a29748bcdd3983e8e75e0b0c770b3515.tar.gz
RSA documentation update.
-rw-r--r--ChangeLog5
-rw-r--r--nettle.texinfo107
2 files changed, 93 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 852af17a..e38d5c78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-10 Niels Möller <nisse@lysator.liu.se>
+
+ * nettle.texinfo (RSA): Document the rsa_pkcs1_verify and
+ rsa_pkcs1_sign functions, and the new rsa_*_tr functions.
+
2015-12-18 Niels Möller <nisse@lysator.liu.se>
* testsuite/testutils.h: Fix include order, system headers before
diff --git a/nettle.texinfo b/nettle.texinfo
index 1b362e29..3af75ed6 100644
--- a/nettle.texinfo
+++ b/nettle.texinfo
@@ -3537,7 +3537,7 @@ F(x) = x^e mod n
I.e. raise x to the @code{e}'th power, while discarding all multiples of
@code{n}. The pair of numbers @code{n} and @code{e} is the public key.
@code{e} can be quite small, even @code{e = 3} has been used, although
-slightly larger numbers are recommended. @code{n} should be about 1000
+slightly larger numbers are recommended. @code{n} should be about 2000
bits or larger.
If @code{n} is large enough, and properly chosen, the inverse of F,
@@ -3546,8 +3546,8 @@ But, where's the trapdoor?
Let's first look at how @acronym{RSA} key-pairs are generated. First
@code{n} is chosen as the product of two large prime numbers @code{p}
-and @code{q} of roughly the same size (so if @code{n} is 1000 bits,
-@code{p} and @code{q} are about 500 bits each). One also computes the
+and @code{q} of roughly the same size (so if @code{n} is 2000 bits,
+@code{p} and @code{q} are about 1000 bits each). One also computes the
number @code{phi = (p-1)(q-1)}, in mathematical speak, @code{phi} is the
order of the multiplicative group of integers modulo n.
@@ -3591,6 +3591,16 @@ from the message in the same way as above. Then @code{s^e mod n} is
computed, the operation returns true if and only if the result equals
@code{x}.
+The @acronym{RSA} algorithm can also be used for encryption. RSA encryption uses
+the public key @code{(n,e)} to compute the ciphertext @code{m^e mod n}.
+The @cite{PKCS#1} padding scheme will use at least 8 random and non-zero
+octets, using @var{m} of the form @code{[00 02 padding 00 plaintext]}.
+It is required that @code{m < n}, and therefor the plaintext must be
+smaller than the octet size of the modulo @code{n}, with some margin.
+
+To decrypt the message, one needs the private key to compute @code{m =
+c^e mod n} followed by checking and removing the padding.
+
@subsubsection Nettle's @acronym{RSA} support
Nettle represents @acronym{RSA} keys using two structures that contain
@@ -3641,17 +3651,60 @@ zero if the key can't be used, for instance if the modulo is smaller
than the minimum size needed for @acronym{RSA} operations specified by PKCS#1.
@end deftypefun
+For each operation using the private key, there are two variants, e.g.,
+@code{rsa_sha256_sign} and @code{rsa_sha256_sign_tr}. The former
+function is older, and it should be avoided, because it provides no
+defenses against side-channel attacks. The latter function use
+randomized @acronym{RSA} blinding, which defends against timing attacks
+using chosen-ciphertext, and it also checks the correctness of the
+private key computation using the public key, which defends against
+software or hardware errors which could leak the private key.
+
Before signing or verifying a message, you first hash it with the
appropriate hash function. You pass the hash function's context struct
to the @acronym{RSA} signature function, and it will extract the message
digest and do the rest of the work. There are also alternative functions
-that take the hash digest as argument.
+that take the hash digest as argument.
There is currently no support for using SHA224 or SHA384 with
@acronym{RSA} signatures, since there's no gain in either computation
time nor message size compared to using SHA256 and SHA512, respectively.
-Creation and verification of signatures is done with the following functions:
+Creating an @acronym{RSA} signature is done with one of the following
+functions:
+
+@deftypefun int rsa_md5_sign_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, struct md5_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha1_sign_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, struct sha1_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha256_sign_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, struct sha256_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha512_sign_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, struct sha512_ctx *@var{hash}, mpz_t @var{signature})
+The signature is stored in @var{signature} (which must have been
+@code{mpz_init}'ed earlier). The hash context is reset so that it can be
+used for new messages. The @var{random_ctx} and @var{random} pointers
+are used to generate the @acronym{RSA} blinding. Returns one on success,
+or zero on failure. Signing fails if an error in the computation was
+detected, or if the key is too small for the given hash size, e.g., it's
+not possible to create a signature using SHA512 and a 512-bit
+@acronym{RSA} key.
+@end deftypefun
+
+@deftypefun int rsa_md5_sign_digest_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, const uint8_t *@var{digest}, mpz_t @var{signature})
+@deftypefunx int rsa_sha1_sign_digest_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, const uint8_t *@var{digest}, mpz_t @var{signature})
+@deftypefunx int rsa_sha256_sign_digest_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, const uint8_t *@var{digest}, mpz_t @var{signature})
+@deftypefunx int rsa_sha512_sign_digest_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, const uint8_t *@var{digest}, mpz_t @var{signature})
+Creates a signature from the given hash digest. @var{digest} should
+point to a digest of size @code{MD5_DIGEST_SIZE},
+@code{SHA1_DIGEST_SIZE}, @code{SHA256_DIGEST_SIZE}, or
+@code{SHA512_DIGEST_SIZE}respectively. The signature is stored in
+@var{signature} (which must have been @code{mpz_init}:ed earlier).
+Returns one on success, or zero on failure.
+@end deftypefun
+
+@deftypefun int rsa_pkcs1_sign_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, size_t @var{length}, const uint8_t *@var{digest_info}, mpz_t @var{signature})
+Similar to the above @code{_sign_digest_tr} functions, but the input is not the
+plain hash digest, but a PKCS#1 ``DigestInfo'', an ASN.1 DER-encoding
+of the digest together with an object identifier for the used hash
+algorithm.
+@end deftypefun
@deftypefun int rsa_md5_sign (const struct rsa_private_key *@var{key}, struct md5_ctx *@var{hash}, mpz_t @var{signature})
@deftypefunx int rsa_sha1_sign (const struct rsa_private_key *@var{key}, struct sha1_ctx *@var{hash}, mpz_t @var{signature})
@@ -3669,13 +3722,23 @@ it's not possible to create a signature using SHA512 and a 512-bit
@deftypefunx int rsa_sha1_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
@deftypefunx int rsa_sha256_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
@deftypefunx int rsa_sha512_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
-Creates a signature from the given hash digest. @var{digest} should
-point to a digest of size @code{MD5_DIGEST_SIZE},
-@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively. The
-signature is stored in @var{signature} (which must have been
+Creates a signature from the given hash digest; otherwise analoguous to
+the above signing functions. @var{digest} should point to a digest of
+size @code{MD5_DIGEST_SIZE}, @code{SHA1_DIGEST_SIZE},
+@code{SHA256_DIGEST_SIZE}, or @code{SHA512_DIGEST_SIZE}, respectively.
+The signature is stored in @var{signature} (which must have been
@code{mpz_init}:ed earlier). Returns one on success, or zero on failure.
@end deftypefun
+@deftypefun int rsa_pkcs1_sign(const struct rsa_private_key *@var{key}, size_t @var{length}, const uint8_t *@var{digest_info}, mpz_t @var{s})
+Similar to the above _sign_digest functions, but the input is not the
+plain hash digest, but a PKCS#1 ``DigestInfo'', an ASN.1 DER-encoding
+of the digest together with an object identifier for the used hash
+algorithm.
+@end deftypefun
+
+Verifying an RSA signature is done with one of the following functions:
+
@deftypefun int rsa_md5_verify (const struct rsa_public_key *@var{key}, struct md5_ctx *@var{hash}, const mpz_t @var{signature})
@deftypefunx int rsa_sha1_verify (const struct rsa_public_key *@var{key}, struct sha1_ctx *@var{hash}, const mpz_t @var{signature})
@deftypefunx int rsa_sha256_verify (const struct rsa_public_key *@var{key}, struct sha256_ctx *@var{hash}, const mpz_t @var{signature})
@@ -3688,17 +3751,18 @@ the hash context is reset so that it can be used for new messages.
@deftypefunx int rsa_sha1_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
@deftypefunx int rsa_sha256_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
@deftypefunx int rsa_sha512_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
-Returns 1 if the signature is valid, or 0 if it isn't. @var{digest} should
-point to a digest of size @code{MD5_DIGEST_SIZE},
-@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively.
+Returns 1 if the signature is valid, or 0 if it isn't. @var{digest}
+should point to a digest of size @code{MD5_DIGEST_SIZE},
+@code{SHA1_DIGEST_SIZE}, @code{SHA256_DIGEST_SIZE}, or
+@code{SHA512_DIGEST_SIZE} respectively.
@end deftypefun
-The RSA algorithm can also be used for encryption. RSA encryption uses
-the public key @code{(n,e)} to compute the ciphertext @code{m^e mod n}.
-The PKCS#1 padding scheme will use at least 8 random and non-zero
-octets, using @var{m} of the form @code{[00 02 padding 00 plaintext]}.
-It is required that @code{m < n}, and therefor the plaintext must be
-smaller than the octet size of the modulo @code{n}, with some margin.
+@deftypefun int rsa_pkcs1_verify(const struct rsa_public_key *@var{key}, size_t @var{length}, const uint8_t *@var{digest_info}, const mpz_t @var{signature})
+Similar to the above _verify_digest functions, but the input is not the
+plain hash digest, but a PKCS#1 ``DigestInfo'', and ASN.1 DER-encoding
+of the digest together with an object identifier for the used hash
+algorithm.
+@end deftypefun
The following function is used to encrypt a clear text message using RSA.
@deftypefun int rsa_encrypt (const struct rsa_public_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, size_t @var{length}, const uint8_t *@var{cleartext}, mpz_t @var{ciphertext})
@@ -3724,8 +3788,13 @@ that isn't supported by the above functions Nettle also includes a
function that computes @code{x^d mod n} and nothing more, using the
@acronym{CRT} optimization.
+@deftypefun int rsa_compute_root_tr(const struct rsa_public_key *@var{pub}, const struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func *@var{random}, mpz_t @var{x}, const mpz_t @var{m})
+Computes @code{x = m^d}. Returns one on success, or zero if a failure in
+the computation was detected.
+@end deftypefun
+
@deftypefun void rsa_compute_root (struct rsa_private_key *@var{key}, mpz_t @var{x}, const mpz_t @var{m})
-Computes @code{x = m^d}, efficiently.
+Computes @code{x = m^d}.
@end deftypefun
At last, how do you create new keys?