diff libtomcrypt/src/pk/rsa/rsa_exptmod.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
line wrap: on
line diff
--- a/libtomcrypt/src/pk/rsa/rsa_exptmod.c	Thu Feb 08 23:11:40 2018 +0800
+++ b/libtomcrypt/src/pk/rsa/rsa_exptmod.c	Fri Feb 09 21:44:05 2018 +0800
@@ -5,41 +5,43 @@
  *
  * The library is free for all purposes without any express
  * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
  */
 #include "tomcrypt.h"
 
 /**
   @file rsa_exptmod.c
-  RSA LTC_PKCS exptmod, Tom St Denis
-*/  
+  RSA PKCS exptmod, Tom St Denis
+  Added RSA blinding --nmav
+*/
 
 #ifdef LTC_MRSA
 
-/** 
-   Compute an RSA modular exponentiation 
+/**
+   Compute an RSA modular exponentiation
    @param in         The input data to send into RSA
    @param inlen      The length of the input (octets)
-   @param out        [out] The destination 
+   @param out        [out] The destination
    @param outlen     [in/out] The max size and resulting size of the output
    @param which      Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC
-   @param key        The RSA key to use 
+   @param key        The RSA key to use
    @return CRYPT_OK if successful
-*/   
+*/
 int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
                       unsigned char *out,  unsigned long *outlen, int which,
                       rsa_key *key)
 {
-   void         *tmp, *tmpa, *tmpb;
+   void        *tmp, *tmpa, *tmpb;
+   #ifdef LTC_RSA_BLINDING
+   void        *rnd, *rndi /* inverse of rnd */;
+   #endif
    unsigned long x;
-   int           err;
+   int           err, has_crt_parameters;
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(key    != NULL);
-  
+
    /* is the key of the right type for the operation? */
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
       return CRYPT_PK_NOT_PRIVATE;
@@ -51,8 +53,15 @@
    }
 
    /* init and copy into tmp */
-   if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK)                                    { return err; }
-   if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK)                 { goto error; }
+   if ((err = mp_init_multi(&tmp, &tmpa, &tmpb,
+#ifdef LTC_RSA_BLINDING
+                                               &rnd, &rndi,
+#endif /* LTC_RSA_BLINDING */
+                                                           NULL)) != CRYPT_OK)
+        { return err; }
+   if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK)
+        { goto error; }
+
 
    /* sanity check on the input */
    if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
@@ -62,19 +71,75 @@
 
    /* are we using the private exponent and is the key optimized? */
    if (which == PK_PRIVATE) {
-      /* tmpa = tmp^dP mod p */
-      if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK)                               { goto error; }
+      #ifdef LTC_RSA_BLINDING
+      /* do blinding */
+      err = mp_rand(rnd, mp_get_digit_count(key->N));
+      if (err != CRYPT_OK) {
+             goto error;
+      }
+
+      /* rndi = 1/rnd mod N */
+      err = mp_invmod(rnd, key->N, rndi);
+      if (err != CRYPT_OK) {
+             goto error;
+      }
 
-      /* tmpb = tmp^dQ mod q */
-      if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK)                               { goto error; }
+      /* rnd = rnd^e */
+      err = mp_exptmod( rnd, key->e, key->N, rnd);
+      if (err != CRYPT_OK) {
+             goto error;
+      }
+
+      /* tmp = tmp*rnd mod N */
+      err = mp_mulmod( tmp, rnd, key->N, tmp);
+      if (err != CRYPT_OK) {
+             goto error;
+      }
+      #endif /* LTC_RSA_BLINDING */
+
+      has_crt_parameters = (key->p != NULL) && (mp_get_digit_count(key->p) != 0) &&
+                              (key->q != NULL) && (mp_get_digit_count(key->q) != 0) &&
+                                 (key->dP != NULL) && (mp_get_digit_count(key->dP) != 0) &&
+                                    (key->dQ != NULL) && (mp_get_digit_count(key->dQ) != 0) &&
+                                       (key->qP != NULL) && (mp_get_digit_count(key->qP) != 0);
 
-      /* tmp = (tmpa - tmpb) * qInv (mod p) */
-      if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK)                                              { goto error; }
-      if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK)                                { goto error; }
+      if (!has_crt_parameters) {
+         /*
+          * In case CRT optimization parameters are not provided,
+          * the private key is directly used to exptmod it
+          */
+         if ((err = mp_exptmod(tmp, key->d, key->N, tmp)) != CRYPT_OK)                              { goto error; }
+      } else {
+         /* tmpa = tmp^dP mod p */
+         if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK)                            { goto error; }
+
+         /* tmpb = tmp^dQ mod q */
+         if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK)                            { goto error; }
+
+         /* tmp = (tmpa - tmpb) * qInv (mod p) */
+         if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK)                                           { goto error; }
+         if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK)                              { goto error; }
 
-      /* tmp = tmpb + q * tmp */
-      if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK)                                             { goto error; }
-      if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK)                                               { goto error; }
+         /* tmp = tmpb + q * tmp */
+         if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK)                                          { goto error; }
+         if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK)                                            { goto error; }
+      }
+
+      #ifdef LTC_RSA_BLINDING
+      /* unblind */
+      err = mp_mulmod( tmp, rndi, key->N, tmp);
+      if (err != CRYPT_OK) {
+             goto error;
+      }
+      #endif
+
+      #ifdef LTC_RSA_CRT_HARDENING
+      if (has_crt_parameters) {
+         if ((err = mp_exptmod(tmp, key->e, key->N, tmpa)) != CRYPT_OK)                              { goto error; }
+         if ((err = mp_read_unsigned_bin(tmpb, (unsigned char *)in, (int)inlen)) != CRYPT_OK)        { goto error; }
+         if (mp_cmp(tmpa, tmpb) != LTC_MP_EQ)                                     { err = CRYPT_ERROR; goto error; }
+      }
+      #endif
    } else {
       /* exptmod it */
       if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK)                                { goto error; }
@@ -102,12 +167,16 @@
    /* clean up and return */
    err = CRYPT_OK;
 error:
-   mp_clear_multi(tmp, tmpa, tmpb, NULL);
+   mp_clear_multi(
+#ifdef LTC_RSA_BLINDING
+                  rndi, rnd,
+#endif /* LTC_RSA_BLINDING */
+                             tmpb, tmpa, tmp, NULL);
    return err;
 }
 
 #endif
 
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */