comparison libtomcrypt/src/pk/rsa/rsa_exptmod.c @ 382:0cbe8f6dbf9e

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f) to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:41:05 +0000
parents 1b9e69c058d2
children f849a5ca2efc
comparison
equal deleted inserted replaced
379:b66a00272a90 382:0cbe8f6dbf9e
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file rsa_exptmod.c 14 @file rsa_exptmod.c
29 */ 29 */
30 int rsa_exptmod(const unsigned char *in, unsigned long inlen, 30 int rsa_exptmod(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen, int which, 31 unsigned char *out, unsigned long *outlen, int which,
32 rsa_key *key) 32 rsa_key *key)
33 { 33 {
34 mp_int tmp, tmpa, tmpb; 34 void *tmp, *tmpa, *tmpb;
35 unsigned long x; 35 unsigned long x;
36 int err; 36 int err;
37 37
38 LTC_ARGCHK(in != NULL); 38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(out != NULL); 39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL); 40 LTC_ARGCHK(outlen != NULL);
41 LTC_ARGCHK(key != NULL); 41 LTC_ARGCHK(key != NULL);
42 42
43 /* is the key of the right type for the operation? */ 43 /* is the key of the right type for the operation? */
44 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { 44 if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
45 return CRYPT_PK_NOT_PRIVATE; 45 return CRYPT_PK_NOT_PRIVATE;
46 } 46 }
47 47
49 if (which != PK_PRIVATE && which != PK_PUBLIC) { 49 if (which != PK_PRIVATE && which != PK_PUBLIC) {
50 return CRYPT_PK_INVALID_TYPE; 50 return CRYPT_PK_INVALID_TYPE;
51 } 51 }
52 52
53 /* init and copy into tmp */ 53 /* init and copy into tmp */
54 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != MP_OKAY) { return mpi_to_ltc_error(err); } 54 if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; }
55 if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } 55 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; }
56 56
57 /* sanity check on the input */ 57 /* sanity check on the input */
58 if (mp_cmp(&key->N, &tmp) == MP_LT) { 58 if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
59 err = CRYPT_PK_INVALID_SIZE; 59 err = CRYPT_PK_INVALID_SIZE;
60 goto done; 60 goto error;
61 } 61 }
62 62
63 /* are we using the private exponent and is the key optimized? */ 63 /* are we using the private exponent and is the key optimized? */
64 if (which == PK_PRIVATE) { 64 if (which == PK_PRIVATE) {
65 /* tmpa = tmp^dP mod p */ 65 /* tmpa = tmp^dP mod p */
66 if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY) { goto error; } 66 if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; }
67 67
68 /* tmpb = tmp^dQ mod q */ 68 /* tmpb = tmp^dQ mod q */
69 if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY) { goto error; } 69 if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; }
70 70
71 /* tmp = (tmpa - tmpb) * qInv (mod p) */ 71 /* tmp = (tmpa - tmpb) * qInv (mod p) */
72 if ((err = mp_sub(&tmpa, &tmpb, &tmp)) != MP_OKAY) { goto error; } 72 if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; }
73 if ((err = mp_mulmod(&tmp, &key->qP, &key->p, &tmp)) != MP_OKAY) { goto error; } 73 if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; }
74 74
75 /* tmp = tmpb + q * tmp */ 75 /* tmp = tmpb + q * tmp */
76 if ((err = mp_mul(&tmp, &key->q, &tmp)) != MP_OKAY) { goto error; } 76 if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; }
77 if ((err = mp_add(&tmp, &tmpb, &tmp)) != MP_OKAY) { goto error; } 77 if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; }
78 } else { 78 } else {
79 /* exptmod it */ 79 /* exptmod it */
80 if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; } 80 if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; }
81 } 81 }
82 82
83 /* read it back */ 83 /* read it back */
84 x = (unsigned long)mp_unsigned_bin_size(&key->N); 84 x = (unsigned long)mp_unsigned_bin_size(key->N);
85 if (x > *outlen) { 85 if (x > *outlen) {
86 *outlen = x;
86 err = CRYPT_BUFFER_OVERFLOW; 87 err = CRYPT_BUFFER_OVERFLOW;
87 goto done; 88 goto error;
88 } 89 }
89 90
90 /* this should never happen ... */ 91 /* this should never happen ... */
91 if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) { 92 if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
92 err = CRYPT_ERROR; 93 err = CRYPT_ERROR;
93 goto done; 94 goto error;
94 } 95 }
95 *outlen = x; 96 *outlen = x;
96 97
97 /* convert it */ 98 /* convert it */
98 zeromem(out, x); 99 zeromem(out, x);
99 if ((err = mp_to_unsigned_bin(&tmp, out+(x-mp_unsigned_bin_size(&tmp)))) != MP_OKAY) { goto error; } 100 if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; }
100 101
101 /* clean up and return */ 102 /* clean up and return */
102 err = CRYPT_OK; 103 err = CRYPT_OK;
103 goto done;
104 error: 104 error:
105 err = mpi_to_ltc_error(err); 105 mp_clear_multi(tmp, tmpa, tmpb, NULL);
106 done:
107 mp_clear_multi(&tmp, &tmpa, &tmpb, NULL);
108 return err; 106 return err;
109 } 107 }
110 108
111 #endif 109 #endif
112 110
113 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */ 111 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */
114 /* $Revision: 1.4 $ */ 112 /* $Revision: 1.16 $ */
115 /* $Date: 2005/06/23 02:10:22 $ */ 113 /* $Date: 2006/12/04 03:09:28 $ */