summaryrefslogtreecommitdiff
path: root/cipher/rsa-common.c
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2013-12-22 17:12:28 +0400
committerWerner Koch <wk@gnupg.org>2014-03-04 11:00:12 +0100
commitea8d597726305274214224757b32730644e12bd8 (patch)
treee416eb64049683d4f54353d30a8649995c28dab1 /cipher/rsa-common.c
parent6be3032048ee2466511d2384fcf2d28b856219b2 (diff)
downloadlibgcrypt-ea8d597726305274214224757b32730644e12bd8.tar.gz
Add a simple (raw) PKCS#1 padding mode
* src/cipher.h (PUBKEY_ENC_PKCS1_RAW): New. * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Handle pkcs1-raw flag. * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Handle s-exp like (data (flags pkcs1-raw) (value xxxxx)) * cipher/rsa-common.c (_gcry_rsa_pkcs1_encode_raw_for_sig): PKCS#1-encode data with embedded hash OID for signature verification. * tests/basic.c (check_pubkey_sign): Add tests for s-exps with pkcs1-raw flag. -- Allow user to specify (flags pkcs1-raw) to enable pkcs1 padding of raw value (no hash algorithm is specified). It is up to the user to verify that the passed value is properly formatted and includes DER-encoded ASN OID of the used hash function. Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Diffstat (limited to 'cipher/rsa-common.c')
-rw-r--r--cipher/rsa-common.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c
index 4f5a6594..f56e9896 100644
--- a/cipher/rsa-common.c
+++ b/cipher/rsa-common.c
@@ -319,6 +319,71 @@ _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
return rc;
}
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+ type 1 padding. On success the result is stored as a new MPI at
+ R_RESULT. On error the value at R_RESULT is undefined.
+
+ We encode the value in this way:
+
+ 0 1 PAD(n bytes) 0 VALUE(valuelen bytes)
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 1 is the block type.
+ PAD consists of 0xff bytes.
+ 0 marks the end of the padding.
+
+ (Note that PGP prior to version 2.3 encoded the message digest as:
+ 0 1 MD(16 bytes) 0 PAD(n bytes) 1
+ The MD is always 16 bytes here because it's always MD5. GnuPG
+ does not not support pre-v2.3 signatures, but I'm including this
+ comment so the information is easily found if needed.)
+*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ byte *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+
+ if ( !valuelen || valuelen + 4 > nframe)
+ {
+ /* Can't encode an DLEN byte digest MD into an NFRAME byte
+ frame. */
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if ( !(frame = xtrymalloc (nframe)) )
+ return gpg_err_code_from_syserror ();
+
+ /* Assemble the pkcs#1 block type 1. */
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - valuelen - 3 ;
+ gcry_assert (i > 1);
+ memset (frame+n, 0xff, i );
+ n += i;
+ frame[n++] = 0;
+ memcpy (frame+n, value, valuelen );
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ /* Convert it into an MPI. */
+ err = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+ xfree (frame);
+
+ return rc;
+}
+
/* Mask generation function for OAEP. See RFC-3447 B.2.1. */
static gcry_err_code_t