X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Fpkcs1.c;h=6e5a6a4a560b181774b0ab82364fb5e5503458dd;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=c3136f58eef0d4b39e9d625279dd07e429120a97;hpb=02c161c97dd908adc4d78b8faf2ca9eb3cc1379d;p=silc.git diff --git a/lib/silccrypt/pkcs1.c b/lib/silccrypt/pkcs1.c index c3136f58..6e5a6a4a 100644 --- a/lib/silccrypt/pkcs1.c +++ b/lib/silccrypt/pkcs1.c @@ -1,13 +1,15 @@ +/* $Id$ */ /* PKCS #1 RSA wrapper. - Heavily modified to work under SILC, code that is not needed in SILC has - been removed for good, and some code was fixed and changed. + Heavily modified to work under SILC, rewrote all interfaces, code that + is not needed in SILC has been removed for good, and some code was fixed + and changed. For example, RSA_DecodeOneBlock was not used at all by Mozilla, however, - I took this code in to use after doing some fixing. Also, OAEP is removed - totally for now. I'm not sure whether OAEP could be used in the future - with SILC but not for now. + I took this code in to use after doing some fixing (it had some bugs). + Also, OAEP is removed totally for now. I'm not sure whether OAEP could + be used in the future with SILC but not for now. This file also implements partial SILC PKCS API for RSA with PKCS #1. It is partial because all the other functions but encrypt, decrypt, @@ -25,15 +27,15 @@ Hence, the encoding is always in PKCS #1 version 1.5 format. Any questions and comments regarding this modified version should be - sent to priikone@poseidon.pspt.fi. + sent to priikone@silcnet.org. References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc, ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc, and RFC 2437. - Copyright notice: All code, including the SILC PKCS API code that is - not part of the Mozilla code, falls under the same license found attached - to this file, below. + Copyright notice: All code in this file, including the SILC PKCS API + code that is not part of the Mozilla code, falls under the same license + (MPL or GPL) found attached to this file, below. */ /* @@ -75,6 +77,8 @@ */ #include "silcincludes.h" +#include "rsa_internal.h" +#include "rsa.h" #define RSA_BLOCK_MIN_PAD_LEN 8 #define RSA_BLOCK_FIRST_OCTET 0x00 @@ -101,8 +105,8 @@ typedef enum { * the rules defined in PKCS #1. */ static unsigned char * -RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, - unsigned char *data, unsigned int data_len) +RSA_FormatOneBlock(SilcUInt32 modulusLen, RSA_BlockType blockType, + unsigned char *data, SilcUInt32 data_len) { unsigned char *block; unsigned char *bp; @@ -150,7 +154,6 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, * Blocks intended for public-key operation. */ case RSA_BlockPublic: - /* * 0x00 || BT || Pad || 0x00 || ActualData * 1 1 padLen 1 data_len @@ -161,17 +164,15 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, for (i = 0; i < padLen; i++) { /* Pad with non-zero random data. */ do { - RNG_GenerateGlobalRandomBytes(bp + i, 1); + bp[i] = silc_rng_global_get_byte(); } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); } bp += padLen; *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; memcpy(bp, data, data_len); - break; default: - assert(0); silc_free(block); return NULL; } @@ -180,10 +181,10 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, } static int -RSA_FormatBlock(unsigned char **result, unsigned int *result_len, - unsigned modulusLen, +RSA_FormatBlock(unsigned char **result, SilcUInt32 *result_len, + SilcUInt32 modulusLen, RSA_BlockType blockType, unsigned char *data, - unsigned int data_len) + SilcUInt32 data_len) { /* * XXX For now assume that the data length fits in a single @@ -210,7 +211,7 @@ RSA_FormatBlock(unsigned char **result, unsigned int *result_len, */ assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))); - *result = RSA_FormatOneBlock(modulusLen, blockType, data); + *result = RSA_FormatOneBlock(modulusLen, blockType, data, data_len); if (result == NULL) { *result_len = 0; return FALSE; @@ -237,24 +238,26 @@ RSA_FormatBlock(unsigned char **result, unsigned int *result_len, */ unsigned char * RSA_DecodeOneBlock(unsigned char *data, - unsigned int modulusLen, - unsigned int expectedLen, + SilcUInt32 modulusLen, + SilcUInt32 expectedLen, RSA_BlockType bt, - unsigned int *pResultLen) + SilcUInt32 *pResultLen) { RSA_BlockType blockType; unsigned char *dp, *res; - unsigned int i, len; + SilcUInt32 i, len = 0; dp = data; - if (*dp++ != RSA_BLOCK_FIRST_OCTET) { + if (dp[0] != RSA_BLOCK_FIRST_OCTET) { return NULL; } - blockType = (RSA_BlockType)*dp++; + blockType = (RSA_BlockType)dp[1]; if (blockType != bt) return NULL; + dp += 2; + switch (blockType) { case RSA_BlockPrivate0: /* Ignored */ @@ -267,10 +270,8 @@ RSA_DecodeOneBlock(unsigned char *data, if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET) break; } - if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) { + if (i == modulusLen) return NULL; - } - dp++; len = modulusLen - (dp - data); res = (unsigned char *) silc_malloc(len); if (res == NULL) { @@ -284,10 +285,8 @@ RSA_DecodeOneBlock(unsigned char *data, if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET) break; } - if (i == modulusLen) { + if (i == modulusLen) return NULL; - } - dp++; len = modulusLen - (dp - data); res = (unsigned char *) silc_malloc(len); if (res == NULL) { @@ -315,19 +314,20 @@ RSA_DecodeOneBlock(unsigned char *data, SILC_PKCS_API_ENCRYPT(pkcs1) { RsaKey *key = (RsaKey *)context; - int i, ret = TRUE; - SilcInt mp_tmp; - SilcInt mp_dst; + SilcMPInt mp_tmp; + SilcMPInt mp_dst; unsigned char *padded; - unsigned int padded_len; + SilcUInt32 padded_len, len = key->bits / 8; /* Pad data */ - if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8, + if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPublic, src, src_len)) return FALSE; - silc_mp_init_set_ui(&mp_tmp, 0); - silc_mp_init_set_ui(&mp_dst, 0); + silc_mp_init(&mp_tmp); + silc_mp_init(&mp_dst); + silc_mp_set_ui(&mp_tmp, 0); + silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ silc_mp_bin2mp(padded, padded_len, &mp_tmp); @@ -336,28 +336,29 @@ SILC_PKCS_API_ENCRYPT(pkcs1) rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n); /* MP to data */ - if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len)) - ret = FALSE; + silc_mp_mp2bin_noalloc(&mp_dst, dst, len); + *dst_len = len; memset(padded, 0, padded_len); silc_free(padded); - silc_mp_clear(&mp_tmp); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp); + silc_mp_uninit(&mp_dst); - return ret; + return TRUE; } SILC_PKCS_API_DECRYPT(pkcs1) { RsaKey *key = (RsaKey *)context; - int i, tmplen; - SilcInt mp_tmp; - SilcInt mp_dst; + SilcMPInt mp_tmp; + SilcMPInt mp_dst; unsigned char *padded, *unpadded; - unsigned int padded_len; + SilcUInt32 padded_len; - silc_mp_init_set_ui(&mp_tmp, 0); - silc_mp_init_set_ui(&mp_dst, 0); + silc_mp_init(&mp_tmp); + silc_mp_init(&mp_dst); + silc_mp_set_ui(&mp_tmp, 0); + silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ silc_mp_bin2mp(src, src_len, &mp_tmp); @@ -366,7 +367,7 @@ SILC_PKCS_API_DECRYPT(pkcs1) rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n); /* MP to data */ - padded = silc_mp_mp2bin(&mp_dst, &padded_len); + padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len); /* Unpad data */ unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, @@ -374,8 +375,8 @@ SILC_PKCS_API_DECRYPT(pkcs1) if (!unpadded) { memset(padded, 0, padded_len); silc_free(padded); - silc_mp_clear(&mp_tmp); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp); + silc_mp_uninit(&mp_dst); return FALSE; } @@ -387,8 +388,8 @@ SILC_PKCS_API_DECRYPT(pkcs1) memset(unpadded, 0, padded_len); silc_free(padded); silc_free(unpadded); - silc_mp_clear(&mp_tmp); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp); + silc_mp_uninit(&mp_dst); return TRUE; } @@ -396,49 +397,53 @@ SILC_PKCS_API_DECRYPT(pkcs1) SILC_PKCS_API_SIGN(pkcs1) { RsaKey *key = (RsaKey *)context; - int i, ret = TRUE; - SilcInt mp_tmp; - SilcInt mp_dst; + SilcMPInt mp_tmp; + SilcMPInt mp_dst; unsigned char *padded; - unsigned int padded_len; + SilcUInt32 padded_len; + SilcUInt32 len = key->bits / 8; /* Pad data */ - if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8, - RSA_BlockPrivate, src, src_len)) + if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, + src, src_len)) return FALSE; - silc_mp_init_set_ui(&mp_tmp, 0); - silc_mp_init_set_ui(&mp_dst, 0); + silc_mp_init(&mp_tmp); + silc_mp_init(&mp_dst); + silc_mp_set_ui(&mp_tmp, 0); + silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ - silc_mp_bin2mp(padded, padded_len, &mp_tmp); + silc_mp_bin2mp(padded, len, &mp_tmp); /* Sign */ rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n); /* MP to data */ - if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len)) - ret = FALSE; + silc_mp_mp2bin_noalloc(&mp_dst, dst, len); + *dst_len = len; memset(padded, 0, padded_len); silc_free(padded); - silc_mp_clear(&mp_tmp); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp); + silc_mp_uninit(&mp_dst); - return ret; + return TRUE; } SILC_PKCS_API_VERIFY(pkcs1) { RsaKey *key = (RsaKey *)context; - int i, ret = TRUE; - SilcInt mp_tmp, mp_tmp2; - SilcInt mp_dst; - unsigned char *verify, unpadded; - unsigned int verify_len; + int ret = TRUE; + SilcMPInt mp_tmp2; + SilcMPInt mp_dst; + unsigned char *verify, *unpadded; + SilcUInt32 verify_len, len = key->bits / 8; - silc_mp_init_set_ui(&mp_tmp2, 0); - silc_mp_init_set_ui(&mp_dst, 0); + silc_mp_init(&mp_tmp2); + silc_mp_init(&mp_dst); + silc_mp_set_ui(&mp_tmp2, 0); + silc_mp_set_ui(&mp_dst, 0); /* Format the signature into MP int */ silc_mp_bin2mp(signature, signature_len, &mp_tmp2); @@ -447,16 +452,16 @@ SILC_PKCS_API_VERIFY(pkcs1) rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n); /* MP to data */ - verify = silc_mp_mp2bin(&mp_dst, &verify_len); + verify = silc_mp_mp2bin(&mp_dst, len, &verify_len); /* Unpad data */ - unpadded = RSA_DecodeOneBlock(verify, verify_len, 0, + unpadded = RSA_DecodeOneBlock(verify, len, 0, RSA_BlockPrivate, &verify_len); if (!unpadded) { memset(verify, 0, verify_len); silc_free(verify); - silc_mp_clear(&mp_tmp2); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp2); + silc_mp_uninit(&mp_dst); return FALSE; } @@ -468,8 +473,8 @@ SILC_PKCS_API_VERIFY(pkcs1) memset(unpadded, 0, verify_len); silc_free(verify); silc_free(unpadded); - silc_mp_clear(&mp_tmp2); - silc_mp_clear(&mp_dst); + silc_mp_uninit(&mp_tmp2); + silc_mp_uninit(&mp_dst); return ret; }