home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / utilities / cli / pgp2 / src / c / rsaglue1 < prev    next >
Encoding:
Text File  |  1995-03-11  |  10.1 KB  |  345 lines

  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. #ifdef MIT
  104.         i == -1;
  105. #else
  106.         i = -1;
  107. #endif
  108.  
  109. Cleanup:
  110.     mp_burn(temp);
  111.     return i < 0 ? i : 0;
  112. } /* rsa_public_encrypt */
  113.  
  114. int
  115. rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
  116.      unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
  117. /* Encrypt a message digest with a private key.
  118.  * Returns <0 on error:
  119.  * -1: generic error
  120.  * -4: Key too big
  121.  * -5: Key too small
  122.  */
  123. {
  124.     unit temp[MAX_UNIT_PRECISION];
  125.     unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
  126.     byte *p;
  127.     int i;
  128.     unsigned int blocksize;
  129.  
  130.     /* PGP doesn't store these coefficents, so we need to compute them. */
  131.     mp_move(temp,P);
  132.     mp_dec(temp);
  133.     mp_mod(DP,D,temp);
  134.     mp_move(temp,Q);
  135.     mp_dec(temp);
  136.     mp_mod(DQ,D,temp);
  137.  
  138.     p = (byte *)temp;
  139.  
  140.  
  141.     /* We are building the mpi in place, except for a possible
  142.      * byte-order swap to little-endian at the end.  Thus, we
  143.      * need to fill the buffer with leading 0's in the unused
  144.      * most significant byte positions.
  145.      */
  146.     blocksize = countbytes(N) - 1;    /* Space available for data */
  147.     for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
  148.         *p++ = 0;
  149.  
  150.     i = blocksize - 2 - bytes;        /* Padding needed */
  151.     i -= sizeof(asn_array);        /* Space for type encoding */
  152.     if (i < 0) {
  153.         i = -4;            /* Error code */
  154.         goto Cleanup;
  155.     }
  156.     *p++ = MD_ENCRYPTED_BYTE;    /* Type byte */
  157.     memset(p, ~0, i);        /* All 1's padding */
  158.     p += i;
  159.     *p++ = 0;            /* Zero framing byte */
  160.     memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
  161.     p += sizeof(asn_array);
  162.     memcpy(p, inbuf, bytes);    /* User data */
  163.  
  164.     mp_convert_order((byte *)temp);
  165.     i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U);    /* Encrypt */
  166.     if (i < 0)
  167.         i = -1;
  168.  
  169. Cleanup:
  170.     burn(temp);
  171.  
  172.     return i;
  173. } /* rsa_private_encrypt */
  174.  
  175. /* Remove a signature packet from an MPI */
  176. /* Thus, we expect constant padding and the MIC ASN sequence */
  177. int
  178. rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
  179.     unitptr E, unitptr N)
  180. /* Decrypt a message digest using a public key.  Returns the number of bytes
  181.  * extracted, or <0 on error.
  182.  * -1: Corrupted packet.
  183.  * -3: Key too big
  184.  * -4: Key too small
  185.  * -5: Maybe malformed RSA packet
  186.  * -7: Unknown conventional algorithm
  187.  * -9: Malformed RSA packet
  188.  */
  189. {
  190.     unit temp[MAX_UNIT_PRECISION];
  191.     unsigned int blocksize;
  192.     int i;
  193.     byte *front, *back;
  194.  
  195.     i = mp_modexp(temp, inbuf, E, N);
  196.     if (i < 0) {
  197.         mp_burn(temp);
  198.         return -1;
  199.     }
  200.     mp_convert_order((byte *)temp);
  201.     blocksize = countbytes(N) - 1;
  202.     front = (byte *)temp;            /* Points to start of block */
  203.     i = units2bytes(global_precision);
  204.     back = front + i;            /* Points to end of block */
  205.     i -= countbytes(N) - 1;            /* Expected leading 0's */
  206.  
  207.     /*
  208.      * Strip off the padding.  This handles both PKCS and PGP 2.0
  209.      * formats.  If we're using RSAREF2, we use the padding-removal
  210.      * code in RSAPublicDecrypt, which accepts only PKCS style.
  211.      * Oh, well.
  212.      */
  213.  
  214.     if (i < 0)                /* This shouldn't happen */
  215.         goto ErrorReturn;
  216.     while (i--)                /* Extra bytes should be 0 */
  217.         if (*front++)
  218.             goto ErrorReturn;
  219.  
  220.     /* How to distinguish old PGP from PKCS formats.
  221.      * The old PGP format ends in a trailing type byte, with
  222.      * all 1's padding before that.  The PKCS format ends in
  223.      * 16 bytes of message digest, preceded by an ASN string
  224.      * which is not all 1's.
  225.      */
  226.     if (back[-1] == MD_ENCRYPTED_BYTE &&
  227.         back[-17] == 0xff && back[-18] == 0xff) {
  228.         /* Old PGP format: Padding is at the end */
  229.         if (*--back != MD_ENCRYPTED_BYTE)
  230.             goto ErrorReturn;
  231.         if (*front++ != MD5_ALGORITHM_BYTE) {
  232.             mp_burn(temp);
  233.             return -7;
  234.         }
  235.         while (*--back == 0xff)    /* Skip constant padding */
  236.             ;
  237.         if (*back)        /* It should end with a zero */
  238.             goto ErrorReturn;
  239.     } else {
  240.         /* PKCS format: padding at the beginning */
  241.         if (*front++ != MD_ENCRYPTED_BYTE)
  242.             goto ErrorReturn;
  243.         while (*front++ == 0xff) /* Skip constant padding */
  244.             ;
  245.         if (front[-1])    /* First non-FF byte should be 0 */
  246.             goto ErrorReturn;
  247.         /* Then comes the ASN header */
  248.         if (memcmp(front, asn_array, sizeof(asn_array))) {
  249.             mp_burn(temp);
  250.             return -7;
  251.         }
  252.         front += sizeof(asn_array);
  253.     }
  254.  
  255. /* We're done - copy user data to outbuf */
  256.     if (back < front)
  257.         goto ErrorReturn;
  258.     blocksize = back-front;
  259.     memcpy(outbuf, front, blocksize);
  260.     mp_burn(temp);
  261.     return blocksize;
  262. ErrorReturn:
  263.     mp_burn(temp);
  264.     return -9;
  265. } /* rsa_public_decrypt */
  266.  
  267. /* We expect to find random padding and an encryption key */
  268. int
  269. rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
  270.      unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
  271. /* Decrypt an encryption key using a private key.  Returns the number of bytes
  272.  * extracted, or <0 on error.
  273.  * -1: Generic error
  274.  * -3: Key too big
  275.  * -4: Key too small
  276.  * -5: Maybe malformed RSA
  277.  * -7: Unknown conventional algorithm
  278.  * -9: Malformed RSA packet
  279.  */
  280. {
  281.     byte *back;
  282.     byte *front;
  283.     unsigned int blocksize;
  284.     unit temp[MAX_UNIT_PRECISION];
  285.     unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
  286.     int i;
  287.  
  288.     /* PGP doesn't store (d mod p-1) and (d mod q-1), so compute 'em */
  289.     mp_move(temp,P);
  290.     mp_dec(temp);
  291.     mp_mod(DP,D,temp);
  292.     mp_move(temp,Q);
  293.     mp_dec(temp);
  294.     mp_mod(DQ,D,temp);
  295.  
  296.     i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
  297.     mp_burn(DP);
  298.     mp_burn(DQ);
  299.     if (i < 0) {
  300.         mp_burn(temp);
  301.         return -1;
  302.     }
  303.     mp_convert_order((byte *)temp);
  304.     front = (byte *)temp;            /* Start of block */
  305.     i = units2bytes(global_precision);
  306.     back = (byte *)front + i;        /* End of block */
  307.     blocksize = countbytes(N) - 1;
  308.     i -= blocksize;                /* Expected # of leading 0's */
  309.  
  310.     if (i < 0)                /* This shouldn't happen */
  311.         goto Corrupted;
  312.     while (i--)                /* Extra bytes should be 0 */
  313.         if (*front++)
  314.             goto Corrupted;
  315.  
  316.     /* How to distinguish old PGP from PKCS formats.
  317.      * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
  318.      * while PKCS formats have it leading.
  319.      */
  320.     if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
  321.         /* PGP 2.0 format  - padding at the end */
  322.         if (back[-1] != CK_ENCRYPTED_BYTE)
  323.             goto Corrupted;
  324.         while (*--back)    /* Skip non-zero random padding */
  325.             ;
  326.     } else {
  327.         /* PKCS format - padding at the beginning */
  328.         if (*front++ != CK_ENCRYPTED_BYTE)
  329.             goto Corrupted;
  330.         while (*front++)    /* Skip non-zero random padding */
  331.             ;
  332.     }
  333.     if (back <= front)
  334.         goto Corrupted;
  335.     blocksize = back-front;
  336.  
  337.     memcpy(outbuf, front, blocksize);
  338.     mp_burn(temp);
  339.     return blocksize;
  340.  
  341. Corrupted:
  342.     mp_burn(temp);
  343.     return -9;
  344. } /* rsa_private_decrypt */
  345.