]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/katja/katja_exptmod.c
remove md2 md4 md5 hashes
[zpackage] / libtomcrypt / src / pk / katja / katja_exptmod.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12   @file katja_exptmod.c
13   Katja PKCS-style exptmod, Tom St Denis
14 */
15
16 #ifdef LTC_MKAT
17
18 /**
19    Compute an RSA modular exponentiation
20    @param in         The input data to send into RSA
21    @param inlen      The length of the input (octets)
22    @param out        [out] The destination
23    @param outlen     [in/out] The max size and resulting size of the output
24    @param which      Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC
25    @param key        The RSA key to use
26    @return CRYPT_OK if successful
27 */
28 int katja_exptmod(const unsigned char *in,   unsigned long inlen,
29                         unsigned char *out,  unsigned long *outlen, int which,
30                         katja_key *key)
31 {
32    void         *tmp, *tmpa, *tmpb;
33    unsigned long x;
34    int           err;
35
36    LTC_ARGCHK(in     != NULL);
37    LTC_ARGCHK(out    != NULL);
38    LTC_ARGCHK(outlen != NULL);
39    LTC_ARGCHK(key    != NULL);
40
41    /* is the key of the right type for the operation? */
42    if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
43       return CRYPT_PK_NOT_PRIVATE;
44    }
45
46    /* must be a private or public operation */
47    if (which != PK_PRIVATE && which != PK_PUBLIC) {
48       return CRYPT_PK_INVALID_TYPE;
49    }
50
51    /* init and copy into tmp */
52    if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK)                                    { return err; }
53    if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK)                 { goto error; }
54
55    /* sanity check on the input */
56    if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
57       err = CRYPT_PK_INVALID_SIZE;
58       goto done;
59    }
60
61    /* are we using the private exponent and is the key optimized? */
62    if (which == PK_PRIVATE) {
63       /* tmpa = tmp^dP mod p */
64       if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK)                               { goto error; }
65
66       /* tmpb = tmp^dQ mod q */
67       if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK)                               { goto error; }
68
69       /* tmp = (tmpa - tmpb) * qInv (mod p) */
70       if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK)                                              { goto error; }
71       if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK)                                 { goto error; }
72
73       /* tmp = tmpb + q * tmp */
74       if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK)                                             { goto error; }
75       if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK)                                               { goto error; }
76    } else {
77       /* exptmod it */
78       if ((err = mp_exptmod(tmp, key->N, key->N, tmp)) != CRYPT_OK)                                 { goto error; }
79    }
80
81    /* read it back */
82    x = (unsigned long)mp_unsigned_bin_size(key->N);
83    if (x > *outlen) {
84       *outlen = x;
85       err = CRYPT_BUFFER_OVERFLOW;
86       goto done;
87    }
88
89    /* this should never happen ... */
90    if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
91       err = CRYPT_ERROR;
92       goto done;
93    }
94    *outlen = x;
95
96    /* convert it */
97    zeromem(out, x);
98    if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK)               { goto error; }
99
100    /* clean up and return */
101    err = CRYPT_OK;
102    goto done;
103 error:
104 done:
105    mp_clear_multi(tmp, tmpa, tmpb, NULL);
106    return err;
107 }
108
109 #endif
110
111 /* ref:         $Format:%D$ */
112 /* git commit:  $Format:%H$ */
113 /* commit time: $Format:%ai$ */