summaryrefslogtreecommitdiff
path: root/release/src/router/matrixssl/src/crypto/peersec/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'release/src/router/matrixssl/src/crypto/peersec/rsa.c')
-rw-r--r--release/src/router/matrixssl/src/crypto/peersec/rsa.c463
1 files changed, 0 insertions, 463 deletions
diff --git a/release/src/router/matrixssl/src/crypto/peersec/rsa.c b/release/src/router/matrixssl/src/crypto/peersec/rsa.c
deleted file mode 100644
index 5d6fcccb..00000000
--- a/release/src/router/matrixssl/src/crypto/peersec/rsa.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * rsa.c
- * Release $Name: MATRIXSSL_1_8_8_OPEN $
- *
- * RSA crypto
- */
-/*
- * Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved.
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from PeerSec Networks
- * at http://www.peersec.com
- *
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#include "../cryptoLayer.h"
-
-/******************************************************************************/
-
-static int32 ssl_rsa_crypt(psPool_t *pool,
- const unsigned char *in, uint32 inlen,
- unsigned char *out, uint32 *outlen,
- sslRsaKey_t *key, int32 type);
-
-static int32 sslUnpadRSA(unsigned char *in, int32 inlen, unsigned char *out,
- int32 outlen, int32 decryptType);
-static int32 sslPadRSA(unsigned char *in, int32 inlen, unsigned char *out,
- int32 outlen, int32 cryptType);
-
-#ifdef USE_RSA_BLINDING
-static int32 tim_mp_exptmod(psPool_t *pool,
- mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m);
-#else
-#define tim_mp_exptmod(p, c, e, d, n, m) mp_exptmod(p, c, d, n, m)
-#endif
-
-/******************************************************************************/
-
-#define RSA_PUBLIC 0x01
-#define RSA_PRIVATE 0x02
-
-/******************************************************************************/
-/*
- Public API wrapper around sslGetEntropy
-*/
-int32 matrixGetRandomBytes(unsigned char *bytes, int32 size)
-{
- return sslGetEntropy(bytes, size);
-}
-
-/******************************************************************************/
-/*
- Primary RSA encryption routine
-*/
-static int32 ssl_rsa_crypt(psPool_t *pool,
- const unsigned char *in, uint32 inlen,
- unsigned char *out, uint32 *outlen,
- sslRsaKey_t *key, int32 type)
-{
- mp_int tmp, tmpa, tmpb;
- unsigned long x;
- int32 res;
-
- if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
- return -1;
- }
-/*
- init and copy into tmp
- */
- if (_mp_init_multi(pool, &tmp, &tmpa, &tmpb, NULL, NULL, NULL, NULL, NULL)
- != MP_OKAY) {
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_init_multi\n", NULL);
- goto error;
- }
- if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int32)inlen) !=
- MP_OKAY) {
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_read_unsigned_bin\n", NULL);
- goto error;
- }
-/*
- sanity check on the input
- */
- if (mp_cmp(&key->N, &tmp) == MP_LT) {
- res = -1;
- goto done;
- }
- if (type == RSA_PRIVATE) {
- if (key->optimized) {
- if (tim_mp_exptmod(pool, &tmp, &key->e, &key->dP, &key->p, &tmpa)
- != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: mp_exptmod dP, p\n", NULL);
- goto error;
- }
- if (tim_mp_exptmod(pool, &tmp, &key->e, &key->dQ, &key->q, &tmpb)
- != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: mp_exptmod dQ, q\n", NULL);
- goto error;
- }
- if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: sub tmpb, tmp\n", NULL);
- goto error;
- }
- if (mp_mulmod(pool, &tmp, &key->qP, &key->p, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: mp_mulmod qP, p\n", NULL);
- goto error;
- }
- if (mp_mul(pool, &tmp, &key->q, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: mp_mul q \n", NULL);
- goto error;
- }
- if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("decrypt error: mp_add tmp \n", NULL);
- goto error;
- }
- } else {
- if (tim_mp_exptmod(pool, &tmp, &key->e, &key->d, &key->N, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_exptmod\n", NULL);
- goto error;
- }
- }
- } else if (type == RSA_PUBLIC) {
- if (mp_exptmod(pool, &tmp, &key->e, &key->N, &tmp) != MP_OKAY) {
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_exptmod\n", NULL);
- goto error;
- }
- } else {
- matrixStrDebugMsg("ssl_rsa_crypt error: invalid type param\n", NULL);
- goto error;
- }
-/*
- read it back
- */
- x = (unsigned long)mp_unsigned_bin_size(&key->N);
- if (x > *outlen) {
- res = -1;
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_unsigned_bin_size\n", NULL);
- goto done;
- }
-/*
- We want the encrypted value to always be the key size. Pad with 0x0
-*/
- while (x < (unsigned long)key->size) {
- *out++ = 0x0;
- x++;
- }
-
- *outlen = x;
-/*
- convert it
- */
- memset(out, 0x0, x);
- if (mp_to_unsigned_bin(pool, &tmp, out+(x-mp_unsigned_bin_size(&tmp)))
- != MP_OKAY) {
- matrixStrDebugMsg("ssl_rsa_crypt error: mp_to_unsigned_bin\n", NULL);
- goto error;
- }
-/*
- clean up and return
- */
- res = 0;
- goto done;
-error:
- res = -1;
-done:
- _mp_clear_multi(&tmp, &tmpa, &tmpb, NULL, NULL, NULL, NULL, NULL);
- return res;
-}
-
-/******************************************************************************/
-/*
- Pad a value to be encrypted by RSA, according to PKCS#1 v1.5
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
- When encrypting a value with RSA, the value is first padded to be
- equal to the public key size using the following method:
- 00 <id> <data> 00 <value to be encrypted>
- - id denotes a public or private key operation
- - if id is private, data is however many non-zero bytes it takes to pad the
- value to the key length (randomLen = keyLen - 3 - valueLen).
- - if id is public, data is FF for the same length as described above
- - There must be at least 8 bytes of data.
-*/
-static int32 sslPadRSA(unsigned char *in, int32 inlen, unsigned char *out,
- int32 outlen, int32 cryptType)
-{
- unsigned char *c;
- int32 randomLen;
-
- randomLen = outlen - 3 - inlen;
- if (randomLen < 8) {
- matrixIntDebugMsg("RSA encryption data too large: %d\n", inlen);
- return -1;
- }
- c = out;
- *c = 0x00;
- c++;
- *c = (unsigned char)cryptType;
- c++;
- if (cryptType == RSA_PUBLIC) {
- while (randomLen-- > 0) {
- *c++ = 0xFF;
- }
- } else {
- if (sslGetEntropy(c, randomLen) < 0) {
- matrixStrDebugMsg("Error gathering RSA pad entropy\n", NULL);
- return -1;
- }
-/*
- SECURITY: Read through the random data and change all 0x0 to 0x01.
- This is per spec that no random bytes should be 0
-*/
- while (randomLen-- > 0) {
- if (*c == 0x0) {
- *c = 0x01;
- }
- c++;
- }
- }
- *c = 0x00;
- c++;
- memcpy(c, in, inlen);
-
- return outlen;
-}
-
-
-#ifdef USE_RSA_PUBLIC_ENCRYPT
-/******************************************************************************/
-/*
- RSA public encryption.
- Always called by SSL client for server auth in ClientKeyExchange
- The outlen param must be set to the strength of the key: key->size
-*/
-int32 matrixRsaEncryptPub(psPool_t *pool, sslRsaKey_t *key,
- unsigned char *in, int32 inlen,
- unsigned char *out, int32 outlen)
-{
- int32 size;
-
- size = key->size;
- if (outlen < size) {
- return -1;
- }
-
- if (sslPadRSA(in, inlen, out, size, RSA_PRIVATE) < 0) {
- return -1;
- }
- if (ssl_rsa_crypt(pool, out, size, out, (uint32*)&outlen, key,
- RSA_PUBLIC) < 0 || outlen != size) {
- return -1;
- }
- return size;
-}
-
-#else /* USE_RSA_PUBLIC_ENCRYPT - Keeps the cipher suite definition clean */
-int32 matrixRsaEncryptPub(psPool_t *pool, sslRsaKey_t *key,
- unsigned char *in, int32 inlen,
- unsigned char *out, int32 outlen)
-{
- if (inlen > outlen) {
- return -1;
- }
- memcpy(out, in, inlen);
- return inlen;
-}
-#endif /* USE_RSA_PUBLIC_ENCRYPT */
-
-/******************************************************************************/
-/*
- Unpad a value decrypted by RSA, according to PKCS#1 v1.5
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
-
- When decrypted, the data will look like the pad, including the inital
- byte (00). Form:
- 00 <decryptType> <random data (min 8 bytes)> 00 <value to be encrypted>
-
- We don't worry about v2 rollback issues because we don't support v2
-*/
-static int32 sslUnpadRSA(unsigned char *in, int32 inlen, unsigned char *out,
- int32 outlen, int32 decryptType)
-{
- unsigned char *c, *end;
-
- if (inlen < outlen + 10) {
- return -1;
- }
- c = in;
- end = in + inlen;
-/*
- Verify the first byte (block type) is correct.
-*/
- if (*c++ != 0x00 || *c != decryptType) {
- return -1;
- }
- c++;
-/*
- Skip over the random, non-zero bytes used as padding
-*/
- while (c < end && *c != 0x0) {
- if (decryptType == RSA_PUBLIC) {
- if (*c != 0xFF) {
- return -1;
- }
- }
- c++;
- }
- c++;
-/*
- The length of the remaining data should be equal to what was expected
- Combined with the initial length check, there must be >= 8 bytes of pad
- ftp://ftp.rsa.com/pub/pdfs/bulletn7.pdf
-*/
- if (end - c != outlen) {
- return -1;
- }
-/*
- Copy the value bytes to the out buffer
-*/
- while (c < end) {
- *out = *c;
- out++; c++;
- }
- return outlen;
-}
-
-/******************************************************************************/
-/*
- Always called by the server to decrypt the ClientKeyExchange
-*/
-int32 matrixRsaDecryptPriv(psPool_t *pool, sslRsaKey_t *key,
- unsigned char *in, int32 inlen,
- unsigned char *out, int32 outlen)
-{
- int32 ptLen;
-
- if (inlen != key->size) {
- return -1;
- }
- ptLen = inlen;
- if (ssl_rsa_crypt(pool, in, inlen, in, (uint32*)&ptLen, key,
- RSA_PRIVATE) < 0 || ptLen != inlen) {
- return -1;
- }
- ptLen = sslUnpadRSA(in, inlen, out, outlen, RSA_PRIVATE);
- memset(in, 0x0, inlen);
- return ptLen;
-}
-
-/******************************************************************************/
-/*
- Called by client as normal part of signature validation from server cert.
- Called by the server if authenticating client in CertificateVerify
-*/
-int32 matrixRsaDecryptPub(psPool_t *pool, sslRsaKey_t *key,
- unsigned char *in, int32 inlen,
- unsigned char *out, int32 outlen)
-{
- int32 ptLen;
-
- if (inlen != key->size) {
- return -1;
- }
- ptLen = inlen;
- if (ssl_rsa_crypt(pool, in, inlen, in, (uint32*)&ptLen, key,
- RSA_PUBLIC) < 0 || ptLen != inlen) {
- return -1;
- }
- if ((ptLen = sslUnpadRSA(in, inlen, out, outlen, RSA_PUBLIC)) < 0) {
- return ptLen;
- }
- return 0;
-}
-
-
-#ifdef USE_RSA_BLINDING
-
-static int32 tim_mp_exptmod(psPool_t *pool,
- mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m)
-{
- int32 err;
- mp_int r, tmp, tmp2;
- unsigned char *rtmp;
- unsigned long rlen;
-/*
- pick random r
- */
- rlen = mp_unsigned_bin_size(n);
-
- rtmp = psMalloc(pool, rlen);
- if (rtmp == NULL) {
- return -8; /* SSL_MEM_ERROR */
- }
- sslGetEntropy(rtmp, rlen);
-
- if ((err = _mp_init_multi(pool, &r, &tmp, &tmp2, NULL, NULL, NULL, NULL,
- NULL)) != MP_OKAY) {
- psFree(rtmp);
- return -1;
- }
-/*
- read in r
- */
- if ((err = mp_read_unsigned_bin(&r, rtmp, rlen)) != MP_OKAY) {
- goto __ERR;
- }
-/*
- compute tmp = r^e
- */
- if ((err = mp_exptmod(pool, &r, e, n, &tmp)) != MP_OKAY) {
- goto __ERR;
- }
-/*
- multiply C into the mix
- */
- if ((err = mp_mulmod(pool, c, &tmp, n, &tmp)) != MP_OKAY) {
- goto __ERR;
- }
-/*
- raise to d
- */
- if ((err = mp_exptmod(pool, &tmp, d, n, &tmp)) != MP_OKAY) {
- goto __ERR;
- }
-/*
- invert r and multiply
- */
- if ((err = mp_invmod(pool, &r, n, &tmp2)) != MP_OKAY) {
- goto __ERR;
- }
-/*
- multiply and we are totally set
- */
- if ((err = mp_mulmod(pool, &tmp, &tmp2, n, m)) != MP_OKAY) {
- goto __ERR;
- }
-
-__ERR: _mp_clear_multi(&r, &tmp, &tmp2, NULL, NULL, NULL, NULL, NULL);
- psFree(rtmp);
- return err;
-}
-#endif /* USE_RSA_BLINDING */
-
-/******************************************************************************/
-
-
-
-
-