Home | History | Annotate | Download | only in libmincrypt
      1 /* rsa.c
      2 **
      3 ** Copyright 2012, The Android Open Source Project
      4 **
      5 ** Redistribution and use in source and binary forms, with or without
      6 ** modification, are permitted provided that the following conditions are met:
      7 **     * Redistributions of source code must retain the above copyright
      8 **       notice, this list of conditions and the following disclaimer.
      9 **     * Redistributions in binary form must reproduce the above copyright
     10 **       notice, this list of conditions and the following disclaimer in the
     11 **       documentation and/or other materials provided with the distribution.
     12 **     * Neither the name of Google Inc. nor the names of its contributors may
     13 **       be used to endorse or promote products derived from this software
     14 **       without specific prior written permission.
     15 **
     16 ** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
     17 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19 ** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22 ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24 ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 */
     27 
     28 #include "mincrypt/rsa.h"
     29 #include "mincrypt/sha.h"
     30 #include "mincrypt/sha256.h"
     31 
     32 // a[] -= mod
     33 static void subM(const RSAPublicKey* key,
     34                  uint32_t* a) {
     35     int64_t A = 0;
     36     int i;
     37     for (i = 0; i < key->len; ++i) {
     38         A += (uint64_t)a[i] - key->n[i];
     39         a[i] = (uint32_t)A;
     40         A >>= 32;
     41     }
     42 }
     43 
     44 // return a[] >= mod
     45 static int geM(const RSAPublicKey* key,
     46                const uint32_t* a) {
     47     int i;
     48     for (i = key->len; i;) {
     49         --i;
     50         if (a[i] < key->n[i]) return 0;
     51         if (a[i] > key->n[i]) return 1;
     52     }
     53     return 1;  // equal
     54 }
     55 
     56 // montgomery c[] += a * b[] / R % mod
     57 static void montMulAdd(const RSAPublicKey* key,
     58                        uint32_t* c,
     59                        const uint32_t a,
     60                        const uint32_t* b) {
     61     uint64_t A = (uint64_t)a * b[0] + c[0];
     62     uint32_t d0 = (uint32_t)A * key->n0inv;
     63     uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
     64     int i;
     65 
     66     for (i = 1; i < key->len; ++i) {
     67         A = (A >> 32) + (uint64_t)a * b[i] + c[i];
     68         B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
     69         c[i - 1] = (uint32_t)B;
     70     }
     71 
     72     A = (A >> 32) + (B >> 32);
     73 
     74     c[i - 1] = (uint32_t)A;
     75 
     76     if (A >> 32) {
     77         subM(key, c);
     78     }
     79 }
     80 
     81 // montgomery c[] = a[] * b[] / R % mod
     82 static void montMul(const RSAPublicKey* key,
     83                     uint32_t* c,
     84                     const uint32_t* a,
     85                     const uint32_t* b) {
     86     int i;
     87     for (i = 0; i < key->len; ++i) {
     88         c[i] = 0;
     89     }
     90     for (i = 0; i < key->len; ++i) {
     91         montMulAdd(key, c, a[i], b);
     92     }
     93 }
     94 
     95 // In-place public exponentiation.
     96 // Input and output big-endian byte array in inout.
     97 static void modpow(const RSAPublicKey* key,
     98                    uint8_t* inout) {
     99     uint32_t a[RSANUMWORDS];
    100     uint32_t aR[RSANUMWORDS];
    101     uint32_t aaR[RSANUMWORDS];
    102     uint32_t* aaa = 0;
    103     int i;
    104 
    105     // Convert from big endian byte array to little endian word array.
    106     for (i = 0; i < key->len; ++i) {
    107         uint32_t tmp =
    108             (inout[((key->len - 1 - i) * 4) + 0] << 24) |
    109             (inout[((key->len - 1 - i) * 4) + 1] << 16) |
    110             (inout[((key->len - 1 - i) * 4) + 2] << 8) |
    111             (inout[((key->len - 1 - i) * 4) + 3] << 0);
    112         a[i] = tmp;
    113     }
    114 
    115     if (key->exponent == 65537) {
    116         aaa = aaR;  // Re-use location.
    117         montMul(key, aR, a, key->rr);  // aR = a * RR / R mod M
    118         for (i = 0; i < 16; i += 2) {
    119             montMul(key, aaR, aR, aR);  // aaR = aR * aR / R mod M
    120             montMul(key, aR, aaR, aaR);  // aR = aaR * aaR / R mod M
    121         }
    122         montMul(key, aaa, aR, a);  // aaa = aR * a / R mod M
    123     } else if (key->exponent == 3) {
    124         aaa = aR;  // Re-use location.
    125         montMul(key, aR, a, key->rr);  /* aR = a * RR / R mod M   */
    126         montMul(key, aaR, aR, aR);     /* aaR = aR * aR / R mod M */
    127         montMul(key, aaa, aaR, a);     /* aaa = aaR * a / R mod M */
    128     }
    129 
    130     // Make sure aaa < mod; aaa is at most 1x mod too large.
    131     if (geM(key, aaa)) {
    132         subM(key, aaa);
    133     }
    134 
    135     // Convert to bigendian byte array
    136     for (i = key->len - 1; i >= 0; --i) {
    137         uint32_t tmp = aaa[i];
    138         *inout++ = tmp >> 24;
    139         *inout++ = tmp >> 16;
    140         *inout++ = tmp >> 8;
    141         *inout++ = tmp >> 0;
    142     }
    143 }
    144 
    145 // Expected PKCS1.5 signature padding bytes, for a keytool RSA signature.
    146 // Has the 0-length optional parameter encoded in the ASN1 (as opposed to the
    147 // other flavor which omits the optional parameter entirely). This code does not
    148 // accept signatures without the optional parameter.
    149 
    150 /*
    151 static const uint8_t sha_padding[RSANUMBYTES] = {
    152     0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    153     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    154     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    155     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    156     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    157     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    158     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    159     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    160     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    161     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    162     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    163     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    164     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    165     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    166     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    167     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    168     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    169     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    170     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    171     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    172     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    173     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    174     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    175     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    176     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    177     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    178     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    179     0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
    180     0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
    181     0x05, 0x00, 0x04, 0x14,
    182 
    183     // 20 bytes of hash go here.
    184     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    185 };
    186 */
    187 
    188 // SHA-1 of PKCS1.5 signature sha_padding for 2048 bit, as above.
    189 // At the location of the bytes of the hash all 00 are hashed.
    190 static const uint8_t kExpectedPadShaRsa2048[SHA_DIGEST_SIZE] = {
    191     0xdc, 0xbd, 0xbe, 0x42, 0xd5, 0xf5, 0xa7, 0x2e,
    192     0x6e, 0xfc, 0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68,
    193     0x7c, 0xfb, 0xf1, 0x67
    194 };
    195 
    196 /*
    197 static const uint8_t sha256_padding[RSANUMBYTES] = {
    198     0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    199     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    200     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    201     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    202     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    203     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    204     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    205     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    206     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    207     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    208     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    209     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    210     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    211     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    212     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    213     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    214     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    215     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    216     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    217     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    218     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    219     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    220     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    221     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    222     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    223     0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
    224     0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
    225     0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20,
    226 
    227     // 32 bytes of hash go here.
    228     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    229     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    230 };
    231 */
    232 
    233 // SHA-256 of PKCS1.5 signature sha256_padding for 2048 bit, as above.
    234 // At the location of the bytes of the hash all 00 are hashed.
    235 static const uint8_t kExpectedPadSha256Rsa2048[SHA256_DIGEST_SIZE] = {
    236     0xab, 0x28, 0x8d, 0x8a, 0xd7, 0xd9, 0x59, 0x92,
    237     0xba, 0xcc, 0xf8, 0x67, 0x20, 0xe1, 0x15, 0x2e,
    238     0x39, 0x8d, 0x80, 0x36, 0xd6, 0x6f, 0xf0, 0xfd,
    239     0x90, 0xe8, 0x7d, 0x8b, 0xe1, 0x7c, 0x87, 0x59,
    240 };
    241 
    242 // Verify a 2048-bit RSA PKCS1.5 signature against an expected hash.
    243 // Both e=3 and e=65537 are supported.  hash_len may be
    244 // SHA_DIGEST_SIZE (== 20) to indicate a SHA-1 hash, or
    245 // SHA256_DIGEST_SIZE (== 32) to indicate a SHA-256 hash.  No other
    246 // values are supported.
    247 //
    248 // Returns 1 on successful verification, 0 on failure.
    249 int RSA_verify(const RSAPublicKey *key,
    250                const uint8_t *signature,
    251                const int len,
    252                const uint8_t *hash,
    253                const int hash_len) {
    254     uint8_t buf[RSANUMBYTES];
    255     int i;
    256     const uint8_t* padding_hash;
    257 
    258     if (key->len != RSANUMWORDS) {
    259         return 0;  // Wrong key passed in.
    260     }
    261 
    262     if (len != sizeof(buf)) {
    263         return 0;  // Wrong input length.
    264     }
    265 
    266     if (hash_len != SHA_DIGEST_SIZE &&
    267         hash_len != SHA256_DIGEST_SIZE) {
    268         return 0;  // Unsupported hash.
    269     }
    270 
    271     if (key->exponent != 3 && key->exponent != 65537) {
    272         return 0;  // Unsupported exponent.
    273     }
    274 
    275     for (i = 0; i < len; ++i) {  // Copy input to local workspace.
    276         buf[i] = signature[i];
    277     }
    278 
    279     modpow(key, buf);  // In-place exponentiation.
    280 
    281     // Xor sha portion, so it all becomes 00 iff equal.
    282     for (i = len - hash_len; i < len; ++i) {
    283         buf[i] ^= *hash++;
    284     }
    285 
    286     // Hash resulting buf, in-place.
    287     switch (hash_len) {
    288         case SHA_DIGEST_SIZE:
    289             padding_hash = kExpectedPadShaRsa2048;
    290             SHA_hash(buf, len, buf);
    291             break;
    292         case SHA256_DIGEST_SIZE:
    293             padding_hash = kExpectedPadSha256Rsa2048;
    294             SHA256_hash(buf, len, buf);
    295             break;
    296         default:
    297             return 0;
    298     }
    299 
    300     // Compare against expected hash value.
    301     for (i = 0; i < hash_len; ++i) {
    302         if (buf[i] != padding_hash[i]) {
    303             return 0;
    304         }
    305     }
    306 
    307     return 1;  // All checked out OK.
    308 }
    309