Annotation of pgp/src/rsaglue1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * rsaglue1.c - These functions wrap and unwrap message digests (MDs) and
                      3:  * data encryption keys (DEKs) in padding and RSA-encrypt them into
                      4:  * multi-precision integers.  This layer of abstraction was introduced
                      5:  * to allow the transparent use of either the RSAREF Cryptographic
                      6:  * Toolkit from RSA Data Security Inc for the RSA calculations (where
                      7:  * the RSA patent applies), or, Philip Zimmermann's mpi library for the
                      8:  * RSA calculations.  The rsaglue.c module from PGP version 2.3a performs
                      9:  * the same functions as this module, but can be compiled to select the
                     10:  * use of mpilib functions instead of RSAREF as the underlying math engine.
                     11:  * That version of rsaglue.c would be suitable where the RSA patent does
                     12:  * not apply, such as Canada.
                     13:  *
                     14:  * This file uses MPILIB to perform the actual encryption and decryption.
                     15:  * It uses the same PKCS format as RSAREF, although it also accepts an older
                     16:  * format used in PGP 2.1.
                     17:  *
                     18:  * (c) Copyright 1990-1994 by Philip Zimmermann.  All rights reserved.
                     19:  * The author assumes no liability for damages resulting from the use
                     20:  * of this software, even if the damage results from defects in this
                     21:  * software.  No warranty is expressed or implied.
                     22:  *
                     23:  * Note that while most PGP source modules bear Philip Zimmermann's
                     24:  * copyright notice, many of them have been revised or entirely written
                     25:  * by contributors who frequently failed to put their names in their
                     26:  * code.  Code that has been incorporated into PGP from other authors
                     27:  * was either originally published in the public domain or is used with
                     28:  * permission from the various authors.
                     29:  *
                     30:  * PGP is available for free to the public under certain restrictions.
                     31:  * See the PGP User's Guide (included in the release package) for
                     32:  * important information about licensing, patent restrictions on
                     33:  * certain algorithms, trademarks, copyrights, and export controls.
                     34:  */
                     35: 
                     36: #include <string.h>    /* for mem*() */
                     37: #include "mpilib.h"
                     38: #include "mpiio.h"
                     39: #include "pgp.h"
                     40: #include "rsaglue.h"
                     41: #include "random.h"    /* for cryptRandByte() */
                     42: 
                     43: /* No RSADSI credit for MPI version */
                     44: char signon_legalese[] = "";
                     45: 
                     46: /* These functions hide all the internal details of RSA-encrypted
                     47:  * keys and digests.  They owe a lot of their heritage to
                     48:  * the preblock() and postunblock() routines in mpiio.c.
                     49:  */
                     50: 
                     51: /* Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER)
                     52:    encoding for RSA/MD5, used in PKCS-format signatures. */
                     53: static byte asn_array[] = {    /* PKCS 01 block type 01 data */
                     54:        0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
                     55:        0x02,0x05,0x05,0x00,0x04,0x10 };
                     56: /* This many bytes from the end, there's a zero byte */
                     57: #define ASN_ZERO_END 3
                     58: 
                     59: int
                     60: rsa_public_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
                     61:         unitptr E, unitptr N)
                     62: /* Encrypt a DEK with a public key.  Returns 0 on success.
                     63:  * <0 means there was an error.
                     64:  * -1: Generic error
                     65:  * -3: Key too big
                     66:  * -4: Key too small
                     67:  */
                     68: {
                     69:        unit temp[MAX_UNIT_PRECISION];
                     70:        unsigned int blocksize;
                     71:        int i;  /* Temporary, and holds error codes */
                     72:        byte *p = (byte *)temp;
                     73: 
                     74:        /*
                     75:         * We are building the mpi in place, except for a possible
                     76:         * byte-order swap to little-endian at the end.  Thus, we
                     77:         * need to fill the buffer with leading 0's in the unused
                     78:         * most significant byte positions.
                     79:         */
                     80:        blocksize = countbytes(N) - 1;  /* Bytes available for user data */
                     81:        for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
                     82:                *p++ = 0;
                     83:        /*
                     84:         * Both the PKCS and PGP 2.0 key formats add a type byte, and a
                     85:         * a framing byte of 0 to the user data.  The remaining space
                     86:         * is filled with random padding.  (PKCS requires that there be
                     87:         * at least 1 byte of padding.)
                     88:         */
                     89:        i = blocksize - 2 - bytes;
                     90: 
                     91:        if (i < 1)              /* Less than minimum padding? */
                     92:                return -4;
                     93:        *p++ = CK_ENCRYPTED_BYTE;       /* Type byte */
                     94:        while (i)                       /* Non-zero random padding */
                     95:                if ((*p = cryptRandByte()))
                     96:                        ++p, --i;
                     97:        *p++ = 0;                       /* Framing byte */
                     98:        memcpy(p, inbuf, bytes);        /* User data */
                     99: 
                    100:        mp_convert_order((byte *)temp);         /* Convert buffer to MPI */
                    101:        i = mp_modexp(outbuf, temp, E, N);      /* Do the encryption */
                    102:        if (i < 0)
                    103:                i == -1;
                    104: 
                    105: Cleanup:
                    106:        mp_burn(temp);
                    107:        return i < 0 ? i : 0;
                    108: } /* rsa_public_encrypt */
                    109: 
                    110: int
                    111: rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
                    112:         unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
                    113: /* Encrypt a message digest with a private key.
                    114:  * Returns <0 on error:
                    115:  * -1: generic error
                    116:  * -4: Key too big
                    117:  * -5: Key too small
                    118:  */
                    119: {
                    120:        unit temp[MAX_UNIT_PRECISION];
                    121:        unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
                    122:        byte *p;
                    123:        int i;
                    124:        unsigned int blocksize;
                    125: 
                    126:        /* PGP doesn't store these coefficents, so we need to compute them. */
                    127:        mp_move(temp,P);
                    128:        mp_dec(temp);
                    129:        mp_mod(DP,D,temp);
                    130:        mp_move(temp,Q);
                    131:        mp_dec(temp);
                    132:        mp_mod(DQ,D,temp);
                    133: 
                    134:        p = (byte *)temp;
                    135: 
                    136: 
                    137:        /* We are building the mpi in place, except for a possible
                    138:         * byte-order swap to little-endian at the end.  Thus, we
                    139:         * need to fill the buffer with leading 0's in the unused
                    140:         * most significant byte positions.
                    141:         */
                    142:        blocksize = countbytes(N) - 1;  /* Space available for data */
                    143:        for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
                    144:                *p++ = 0;
                    145: 
                    146:        i = blocksize - 2 - bytes;              /* Padding needed */
                    147:        i -= sizeof(asn_array);         /* Space for type encoding */
                    148:        if (i < 0) {
                    149:                i = -4;                 /* Error code */
                    150:                goto Cleanup;
                    151:        }
                    152:        *p++ = MD_ENCRYPTED_BYTE;       /* Type byte */
                    153:        memset(p, ~0, i);               /* All 1's padding */
                    154:        p += i;
                    155:        *p++ = 0;                       /* Zero framing byte */
                    156:        memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
                    157:        p += sizeof(asn_array);
                    158:        memcpy(p, inbuf, bytes);        /* User data */
                    159: 
                    160:        mp_convert_order((byte *)temp);
                    161:        i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U);       /* Encrypt */
                    162:        if (i < 0)
                    163:                i = -1;
                    164: 
                    165: Cleanup:
                    166:        burn(temp);
                    167: 
                    168:        return i;
                    169: } /* rsa_private_encrypt */
                    170: 
                    171: /* Remove a signature packet from an MPI */
                    172: /* Thus, we expect constant padding and the MIC ASN sequence */
                    173: int
                    174: rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
                    175:        unitptr E, unitptr N)
                    176: /* Decrypt a message digest using a public key.  Returns the number of bytes
                    177:  * extracted, or <0 on error.
                    178:  * -1: Corrupted packet.
                    179:  * -3: Key too big
                    180:  * -4: Key too small
                    181:  * -5: Maybe malformed RSA packet
                    182:  * -7: Unknown conventional algorithm
                    183:  * -9: Malformed RSA packet
                    184:  */
                    185: {
                    186:        unit temp[MAX_UNIT_PRECISION];
                    187:        unsigned int blocksize;
                    188:        int i;
                    189:        byte *front, *back;
                    190: 
                    191:        i = mp_modexp(temp, inbuf, E, N);
                    192:        if (i < 0) {
                    193:                mp_burn(temp);
                    194:                return -1;
                    195:        }
                    196:        mp_convert_order((byte *)temp);
                    197:        blocksize = countbytes(N) - 1;
                    198:        front = (byte *)temp;                   /* Points to start of block */
                    199:        i = units2bytes(global_precision);
                    200:        back = front + i;                       /* Points to end of block */
                    201:        i -= countbytes(N) - 1;                 /* Expected leading 0's */
                    202: 
                    203:        /*
                    204:         * Strip off the padding.  This handles both PKCS and PGP 2.0
                    205:         * formats.  If we're using RSAREF2, we use the padding-removal
                    206:         * code in RSAPublicDecrypt, which accepts only PKCS style.
                    207:         * Oh, well.
                    208:         */
                    209: 
                    210:        if (i < 0)                              /* This shouldn't happen */
                    211:                goto ErrorReturn;
                    212:        while (i--)                             /* Extra bytes should be 0 */
                    213:                if (*front++)
                    214:                        goto ErrorReturn;
                    215: 
                    216:        /* How to distinguish old PGP from PKCS formats.
                    217:         * The old PGP format ends in a trailing type byte, with
                    218:         * all 1's padding before that.  The PKCS format ends in
                    219:         * 16 bytes of message digest, preceded by an ASN string
                    220:         * which is not all 1's.
                    221:         */
                    222:        if (back[-1] == MD_ENCRYPTED_BYTE &&
                    223:            back[-17] == 0xff && back[-18] == 0xff) {
                    224:                /* Old PGP format: Padding is at the end */
                    225:                if (*--back != MD_ENCRYPTED_BYTE)
                    226:                        goto ErrorReturn;
                    227:                if (*front++ != MD5_ALGORITHM_BYTE) {
                    228:                        mp_burn(temp);
                    229:                        return -7;
                    230:                }
                    231:                while (*--back == 0xff) /* Skip constant padding */
                    232:                        ;
                    233:                if (*back)              /* It should end with a zero */
                    234:                        goto ErrorReturn;
                    235:        } else {
                    236:                /* PKCS format: padding at the beginning */
                    237:                if (*front++ != MD_ENCRYPTED_BYTE)
                    238:                        goto ErrorReturn;
                    239:                while (*front++ == 0xff) /* Skip constant padding */
                    240:                        ;
                    241:                if (front[-1])  /* First non-FF byte should be 0 */
                    242:                        goto ErrorReturn;
                    243:                /* Then comes the ASN header */
                    244:                if (memcmp(front, asn_array, sizeof(asn_array))) {
                    245:                        mp_burn(temp);
                    246:                        return -7;
                    247:                }
                    248:                front += sizeof(asn_array);
                    249:        }
                    250: 
                    251: /* We're done - copy user data to outbuf */
                    252:        if (back < front)
                    253:                goto ErrorReturn;
                    254:        blocksize = back-front;
                    255:        memcpy(outbuf, front, blocksize);
                    256:        mp_burn(temp);
                    257:        return blocksize;
                    258: ErrorReturn:
                    259:        mp_burn(temp);
                    260:        return -9;
                    261: } /* rsa_public_decrypt */
                    262: 
                    263: /* We expect to find random padding and an encryption key */
                    264: int
                    265: rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
                    266:         unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
                    267: /* Decrypt an encryption key using a private key.  Returns the number of bytes
                    268:  * extracted, or <0 on error.
                    269:  * -1: Generic error
                    270:  * -3: Key too big
                    271:  * -4: Key too small
                    272:  * -5: Maybe malformed RSA
                    273:  * -7: Unknown conventional algorithm
                    274:  * -9: Malformed RSA packet
                    275:  */
                    276: {
                    277:        byte *back;
                    278:        byte *front;
                    279:        unsigned int blocksize;
                    280:        unit temp[MAX_UNIT_PRECISION];
                    281:        unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
                    282:        int i;
                    283: 
                    284:        /* PGP doesn't store (d mod p-1) and (d mod q-1), so compute 'em */
                    285:        mp_move(temp,P);
                    286:        mp_dec(temp);
                    287:        mp_mod(DP,D,temp);
                    288:        mp_move(temp,Q);
                    289:        mp_dec(temp);
                    290:        mp_mod(DQ,D,temp);
                    291: 
                    292:        i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
                    293:        mp_burn(DP);
                    294:        mp_burn(DQ);
                    295:        if (i < 0) {
                    296:                mp_burn(temp);
                    297:                return -1;
                    298:        }
                    299:        mp_convert_order((byte *)temp);
                    300:        front = (byte *)temp;                   /* Start of block */
                    301:        i = units2bytes(global_precision);
                    302:        back = (byte *)front + i;               /* End of block */
                    303:        blocksize = countbytes(N) - 1;
                    304:        i -= blocksize;                         /* Expected # of leading 0's */
                    305: 
                    306:        if (i < 0)                              /* This shouldn't happen */
                    307:                goto Corrupted;
                    308:        while (i--)                             /* Extra bytes should be 0 */
                    309:                if (*front++)
                    310:                        goto Corrupted;
                    311: 
                    312:        /* How to distinguish old PGP from PKCS formats.
                    313:         * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
                    314:         * while PKCS formats have it leading.
                    315:         */
                    316:        if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
                    317:                /* PGP 2.0 format  - padding at the end */
                    318:                if (back[-1] != CK_ENCRYPTED_BYTE)
                    319:                        goto Corrupted;
                    320:                while (*--back) /* Skip non-zero random padding */
                    321:                        ;
                    322:        } else {
                    323:                /* PKCS format - padding at the beginning */
                    324:                if (*front++ != CK_ENCRYPTED_BYTE)
                    325:                        goto Corrupted;
                    326:                while (*front++)        /* Skip non-zero random padding */
                    327:                        ;
                    328:        }
                    329:        if (back <= front)
                    330:                goto Corrupted;
                    331:        blocksize = back-front;
                    332: 
                    333:        memcpy(outbuf, front, blocksize);
                    334:        mp_burn(temp);
                    335:        return blocksize;
                    336: 
                    337: Corrupted:
                    338:        mp_burn(temp);
                    339:        return -9;
                    340: } /* rsa_private_decrypt */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.