Annotation of pgp/src/rsaglue.c, revision 1.1

1.1     ! root        1: /* rsaglue.c - These functions wrap and unwrap message digests (MDs) and
        !             2:  * data encryption keys (DEKs) in padding and RSA-encrypt them into
        !             3:  * multi-precision integers.  This layer was introduced to allow the
        !             4:  * transparent use of RSAREF for the encryption (in regions where it is
        !             5:  * legally available - the U.S. and treaty partners), or Philip Zimmermann's
        !             6:  * mpi library (where permitted by patent law - outside the U.S.).
        !             7:  *
        !             8:  * These functions also hide the details of using either PKCS or PGP 2.0
        !             9:  * style padding and encodings within the integers.  See pgformat.doc
        !            10:  * for a detailed description of the formats.
        !            11:  */
        !            12: 
        !            13: #include <string.h>    /* for mem*() */
        !            14: #include "mpilib.h"
        !            15: #include "mpiio.h"
        !            16: #include "pgp.h"
        !            17: #include "rsaglue.h"
        !            18: 
        !            19: #ifdef RSAREF          /* defined (or not) in rsaglue.h */
        !            20: #include "rsaref/test/global.h"
        !            21: #include "rsaref/source/rsa.h"
        !            22: #include "rsaref/source/rsaref.h"
        !            23: 
        !            24: int RSAPublicBlock(byte *dest, unsigned *destbytesptr,
        !            25:                    byte *src, unsigned srcbytes,
        !            26:                    R_RSA_PUBLIC_KEY *PubKey);
        !            27: int RSAPrivateBlock(byte *dest, unsigned *destbytesptr,
        !            28:                     byte *src, unsigned srcbytes,
        !            29:                     R_RSA_PRIVATE_KEY *PrivKey);
        !            30: 
        !            31: /* Functions to convert to and from RSAREF's bignum formats */
        !            32: 
        !            33: void
        !            34: rsaref2reg (unitptr to, byte *from, int frombytes)
        !            35: /* Convert an RSAREF-style MSB-first array of bytes to an mpi-style
        !            36:  * native-byte-order integer.  (global_precision units long.)
        !            37:  */
        !            38: {
        !            39:        int tobytes;
        !            40: 
        !            41:        tobytes = units2bytes (global_precision);
        !            42:        if (tobytes > frombytes) {
        !            43:                memset(to, 0, tobytes - frombytes);
        !            44:                memcpy((byte *)to + tobytes - frombytes, from, frombytes);
        !            45:        } else {
        !            46:                memcpy((byte *)to, from + frombytes - tobytes, tobytes);
        !            47:        }
        !            48: #ifndef HIGHFIRST
        !            49:        hiloswap((byte *)to, tobytes);
        !            50: #endif
        !            51: } /* rsaref2reg */
        !            52: 
        !            53: void
        !            54: reg2rsaref (byte *to, int tobytes, unitptr from)
        !            55: /* Convert the other way, mpi format to an array of bytes. */
        !            56: {
        !            57:        int frombytes;
        !            58: 
        !            59:        frombytes = units2bytes(global_precision);
        !            60: 
        !            61: #ifdef HIGHFIRST
        !            62:        if (tobytes > frombytes) {
        !            63:                memset(to, 0, tobytes-frombytes);
        !            64:                memcpy(to + tobytes - frombytes, (byte *)from, frombytes);
        !            65:        } else {
        !            66:                memcpy(to, (byte *)from + frombytes - tobytes, tobytes);
        !            67:        }
        !            68: #else
        !            69:        if (tobytes > frombytes) {
        !            70:                memcpy(to, (byte *)from, frombytes);
        !            71:                memset(to + frombytes, 0, tobytes-frombytes);
        !            72:        } else {
        !            73:                memcpy(to, (byte *)from, tobytes);
        !            74:        }
        !            75:        hiloswap(to, tobytes);
        !            76: #endif
        !            77: } /* reg2rsaref */
        !            78: 
        !            79: int
        !            80: make_RSA_PUBLIC_KEY(R_RSA_PUBLIC_KEY *rpk, unitptr e, unitptr n)
        !            81: /* Given mpi's e and n, fill in an R_RSA_PUBLIC_KEY structure.
        !            82:  * Returns -1 on error, 0 on success
        !            83:  */
        !            84: {
        !            85:        rpk->bits = countbits(n);
        !            86:        if (rpk->bits > MAX_RSA_MODULUS_BITS)
        !            87:                return -1;
        !            88: 
        !            89:        reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
        !            90:        reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, e);
        !            91:        return 0;
        !            92: } /* make_RSA_PUBLIC_KEY */
        !            93:   
        !            94: /* Returns -1 on error, 0 on success */
        !            95: int
        !            96: make_RSA_PRIVATE_KEY(R_RSA_PRIVATE_KEY *rpk, unitptr e, unitptr d, unitptr p,
        !            97:                      unitptr q, unitptr dp, unitptr dq, unitptr u, unitptr n)
        !            98: /* Given a number of necessary mpi's, fill in an R_RSA_PRIVATE_KEY structure.
        !            99:  * Returns -1 on error, 0 on success
        !           100:  */
        !           101: {
        !           102:        rpk->bits = countbits(n);
        !           103:        if (rpk->bits > MAX_RSA_MODULUS_BITS ||
        !           104:            countbits(p) > MAX_RSA_PRIME_BITS ||
        !           105:            countbits(q) > MAX_RSA_PRIME_BITS)
        !           106:                return -1;
        !           107: 
        !           108:        reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
        !           109:        reg2rsaref(rpk->publicExponent, MAX_RSA_MODULUS_LEN, e);
        !           110:        reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, d);
        !           111:        /* The larger prime (p) first */
        !           112:        reg2rsaref(rpk->prime[0], MAX_RSA_PRIME_LEN, q);
        !           113:        reg2rsaref(rpk->prime[1], MAX_RSA_PRIME_LEN, p);
        !           114:        /* d mod (p-1) and d mod (q-1) */
        !           115:        reg2rsaref(rpk->primeExponent[0], MAX_RSA_PRIME_LEN, dq);
        !           116:        reg2rsaref(rpk->primeExponent[1], MAX_RSA_PRIME_LEN, dp);
        !           117:        /* 1/q mod p */
        !           118:        reg2rsaref(rpk->coefficient, MAX_RSA_PRIME_LEN, u);
        !           119:        return 0;
        !           120: } /* make_RSA_PRIVATE_KEY */
        !           121: 
        !           122: #endif /* RSAREF */
        !           123: 
        !           124: /* These functions hide all the internal details of RSA-encrypted
        !           125:  * keys and digests.  They owe a lot of their heritage to
        !           126:  * the preblock() and postunblock() routines in mpiio.c.
        !           127:  */
        !           128: 
        !           129: /* Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER)
        !           130:    encoding for RSA/MD5, used in PKCS-format signatures. */
        !           131: static byte asn_array[] = {    /* PKCS 01 block type 01 data */
        !           132:        0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
        !           133:        0x02,0x05,0x05,0x00,0x04,0x10 };
        !           134: /* This many bytes from the end, there's a zero byte */
        !           135: #define ASN_ZERO_END 3
        !           136: 
        !           137: int
        !           138: rsa_public_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
        !           139:         unitptr E, unitptr N)
        !           140: /* Encrypt a DEK with a public key.  Returns 0 on success.
        !           141:  * <0 means there was an error
        !           142:  */
        !           143: {
        !           144:        unit temp[MAX_UNIT_PRECISION];
        !           145: #ifdef RSAREF
        !           146:        R_RSA_PUBLIC_KEY PubKey;
        !           147:        R_RANDOM_STRUCT Random;
        !           148: #endif /* RSAREF */
        !           149:        unsigned int blocksize;
        !           150:        byte *p;
        !           151:        int i;  /* Temporary, and holds error codes */
        !           152: 
        !           153:        blocksize = countbytes(N) - 1;  /* Bytes available for user data */
        !           154: 
        !           155:        p = (byte *)temp;
        !           156: 
        !           157: #ifdef RSAREF
        !           158:        /* Fill in the R_RSA_PUBLIC_KEY structure as needed later. */
        !           159:        i = make_RSA_PUBLIC_KEY(&PubKey, E, N);
        !           160:        if (i < 0)
        !           161:                return -1;
        !           162: #else /* !RSAREF */
        !           163:        /* If !RSAREF, we are building the mpi in place, except for a
        !           164:         * possible byte-order swap to little-endian at the end.  Thus,
        !           165:         * we need to fill the buffer with leading 0's in the unused
        !           166:         * most significant byte positions.
        !           167:         */
        !           168:        for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
        !           169:                *p++ = 0;
        !           170: #endif /* !RSAREF */
        !           171: 
        !           172:        /* Both the PKCS and PGP 2.0 key formats add a type byte, and a
        !           173:         * a framing byte of 0 to the user data.  The remaining space
        !           174:         * is filled with random padding.  (PKCS requires that there be
        !           175:         * at least 1 byte of padding.)
        !           176:         */
        !           177:        i = blocksize - 2 - bytes;
        !           178: 
        !           179:        if (pkcs_compat) {
        !           180:                if (i < 1)              /* Less than minimum padding? */
        !           181:                        return -1;
        !           182: #ifndef RSAREF /* Build the packet ourselves */
        !           183:                *p++ = CK_ENCRYPTED_BYTE;       /* Type byte */
        !           184:                while (i)                       /* Non-zero random padding */
        !           185:                        if ((*p = idearand()))
        !           186:                                ++p, --i;
        !           187:                *p++ = 0;                       /* Framing byte */
        !           188:                memcpy(p, inbuf, bytes);        /* User data */
        !           189: #else /* RSAREF */
        !           190:                /* The RSAREF routines have their own random number generator
        !           191:                 * to generate random padding.  The following code seeds it
        !           192:                 * from PGP's random number generator.
        !           193:                 */
        !           194:                R_RandomInit(&Random);
        !           195:                for (;;) {
        !           196:                        R_GetRandomBytesNeeded(&i, &Random);
        !           197:                        if (i <= 0)
        !           198:                                break;
        !           199:                        blocksize = i > sizeof(temp) ? sizeof(temp) : i;
        !           200:                        for (i = 0; i < blocksize; i++)
        !           201:                                ((byte *)temp)[i] = idearand();
        !           202:                        R_RandomUpdate(&Random, (byte *)temp, blocksize);
        !           203:                }
        !           204:                /* Pad and encrypt */
        !           205:                i = RSAPublicEncrypt((byte *)temp, &blocksize,
        !           206:                                     inbuf, bytes, &PubKey, &Random);
        !           207:                R_RandomFinal(&Random); /* Clean up RSAREF's RNG */
        !           208:                burn(Random);           /* Just to be sure */
        !           209: #endif /* RSAREF */
        !           210:        } else {        /* !pkcs_compat */
        !           211:                if (i < 0)
        !           212:                        return -1;
        !           213:                memcpy(p, inbuf, bytes);        /* User data */
        !           214:                p += bytes;
        !           215:                *p++ = 0;                       /* Framing byte */
        !           216:                while (i)                       /* Non-zero random padding */
        !           217:                        if ((*p = idearand()))
        !           218:                                ++p, --i;
        !           219:                *p = CK_ENCRYPTED_BYTE;         /* Type byte */
        !           220: #ifdef RSAREF
        !           221:        /* Do the encryption */
        !           222:        i = RSAPublicBlock((byte *)temp, &blocksize,
        !           223:                           (byte *)temp, blocksize, &PubKey);
        !           224: #endif
        !           225: 
        !           226:        } /* !pkcs_compat */
        !           227: 
        !           228: #ifndef RSAREF
        !           229:        mp_convert_order((byte *)temp);         /* Convert buffer to MPI */
        !           230:        i = mp_modexp(outbuf, temp, E, N);      /* Do the encryption */
        !           231: #else /* RSAREF */
        !           232:        rsaref2reg(outbuf, (byte *)temp, blocksize);
        !           233: #endif /* RSAREF */
        !           234: 
        !           235: Cleanup:
        !           236:        mp_burn(temp);
        !           237: #ifdef RSAREF
        !           238:        burn(PubKey);
        !           239: #endif
        !           240:        return i < 0 ? i : 0;
        !           241: } /* rsa_public_encrypt */
        !           242: 
        !           243: int
        !           244: rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
        !           245:         unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
        !           246: /* Encrypt a message digest with a private key.
        !           247:  * Returns <0 on error.
        !           248:  */
        !           249: {
        !           250:        unit temp[MAX_UNIT_PRECISION];
        !           251:        unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
        !           252: #ifdef RSAREF
        !           253:        R_RSA_PRIVATE_KEY PrivKey;
        !           254: #else
        !           255:        int byte_precision;
        !           256: #endif
        !           257:        unsigned int blocksize;
        !           258:        byte *p;
        !           259:        int i;
        !           260: 
        !           261:        /* PGP doesn't store these coefficents, so we need to compute them. */
        !           262:        mp_move(temp,P);
        !           263:        mp_dec(temp);
        !           264:        mp_mod(DP,D,temp);
        !           265:        mp_move(temp,Q);
        !           266:        mp_dec(temp);
        !           267:        mp_mod(DQ,D,temp);
        !           268: 
        !           269:        blocksize = countbytes(N) - 1;  /* Space available for data */
        !           270: 
        !           271:        p = (byte *)temp;
        !           272: 
        !           273: #ifdef RSAREF
        !           274:        i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
        !           275:        if (i < 0)
        !           276:                goto Cleanup;
        !           277: #else
        !           278:        /* If !RSAREF, we are building the mpi in place, except for a
        !           279:         * possible byte-order swap to little-endian at the end.  Thus,
        !           280:         * we need to fill the buffer with leading 0's in the unused
        !           281:         * most significant byte positions.
        !           282:         */
        !           283:        for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
        !           284:                *p++ = 0;
        !           285: #endif
        !           286:        i = blocksize - 2 - bytes;              /* Padding needed */
        !           287: 
        !           288:        if (pkcs_compat) {
        !           289: #ifndef RSAREF /* Pad the packet ourselves */
        !           290:                i -= sizeof(asn_array);         /* Space for type encoding */
        !           291:                if (i < 0) {
        !           292:                        i = -1;                 /* Error code */
        !           293:                        goto Cleanup;
        !           294:                }
        !           295:                *p++ = MD_ENCRYPTED_BYTE;       /* Type byte */
        !           296:                memset(p, ~0, i);               /* All 1's padding */
        !           297:                p += i;
        !           298:                *p++ = 0;                       /* Zero framing byte */
        !           299: #endif /* !RSAREF */
        !           300:                memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
        !           301:                p += sizeof(asn_array);
        !           302:                memcpy(p, inbuf, bytes);        /* User data */
        !           303: #ifdef RSAREF
        !           304:                /* Pad and encrypt */
        !           305:                RSAPrivateEncrypt((byte *)temp, &blocksize,
        !           306:                                  (byte *)temp, bytes+sizeof(asn_array),
        !           307:                                  &PrivKey);
        !           308: #endif
        !           309:        } else {        /* Not pkcs_compat */
        !           310:                --i;                            /* Space for type byte */
        !           311:                if (i < 0) {
        !           312:                        i = -1;                 /* Error code */
        !           313:                        goto Cleanup;
        !           314:                }
        !           315:                *p++ = MD5_ALGORITHM_BYTE;      /* Algorithm type byte */
        !           316:                memcpy(p, inbuf, bytes);        /* User data */
        !           317:                p += bytes;
        !           318:                *p++ = 0;                       /* Framing byte of 0 */
        !           319:                memset(p, ~0, i);               /* All 1's padding */
        !           320:                p += i;
        !           321:                *p = MD_ENCRYPTED_BYTE;         /* Type byte */
        !           322: 
        !           323: #ifdef RSAREF
        !           324:        /* Do the encryption */
        !           325:        i = RSAPrivateBlock((byte *)temp, &blocksize,
        !           326:                            (byte *)temp, blocksize, &PrivKey);
        !           327: #endif /* RSAREF */
        !           328: 
        !           329:        } /* !pkcs_compat */
        !           330: 
        !           331: #ifndef RSAREF
        !           332:        mp_convert_order((byte *)temp);
        !           333:        i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U);       /* Encrypt */
        !           334: #else /* RSAREF */
        !           335:        rsaref2reg(outbuf, (byte *)temp, blocksize);
        !           336: #endif /* RSAREF */
        !           337: 
        !           338: Cleanup:
        !           339:        mp_burn(temp);
        !           340: #ifdef RSAREF
        !           341:        memset(&PrivKey, 0, sizeof(PrivKey));
        !           342: #endif
        !           343:        return i < 0 ? i : 0;
        !           344: } /* rsa_private_encrypt */
        !           345: 
        !           346: /* Remove a signature packet from an MPI */
        !           347: /* Thus, we expect constant padding and the MIC ASN sequence */
        !           348: int
        !           349: rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
        !           350:        unitptr E, unitptr N)
        !           351: /* Decrypt a message digest using a public key.  Returns the number of bytes
        !           352:  * extracted, or <0 on error.
        !           353:  * -1: Corrupted packet.
        !           354:  * -2: Unrecognized message digest algorithm.
        !           355:  */
        !           356: {
        !           357: #ifdef RSAREF
        !           358:        R_RSA_PUBLIC_KEY PubKey;
        !           359: #endif
        !           360:        unit temp[MAX_UNIT_PRECISION];
        !           361:        unsigned int blocksize;
        !           362:        int i;
        !           363:        byte *front, *back;
        !           364: 
        !           365: #ifdef RSAREF
        !           366:        make_RSA_PUBLIC_KEY(&PubKey, E, N);
        !           367:        blocksize = countbytes(inbuf);
        !           368:        reg2rsaref((byte *)temp, blocksize, inbuf);
        !           369:        RSAPublicBlock((byte *)temp, &blocksize,
        !           370:                           (byte *)temp, blocksize, &PubKey);
        !           371: 
        !           372:        front = (byte *)temp;                   /* The start of the block */
        !           373:        back = front + blocksize;               /* The end */
        !           374:        i = blocksize - countbytes(N) + 1;      /* Expected leading 0's */
        !           375: #else
        !           376:        i = mp_modexp(temp, inbuf, E, N);
        !           377:        if (i < 0) {
        !           378:                mp_burn(temp);
        !           379:                return i;
        !           380:        }
        !           381:        mp_convert_order((byte *)temp);
        !           382:        blocksize = countbytes(N) - 1;
        !           383:        front = (byte *)temp;                   /* Points to start of block */
        !           384:        i = units2bytes(global_precision);
        !           385:        back = front + i;                       /* Points to end of block */
        !           386:        i -= countbytes(N) - 1;                 /* Expected leading 0's */
        !           387: #endif
        !           388: 
        !           389:        /* This could be stricter, but the length returned by the RSAREF code
        !           390:           is not documented too well. */
        !           391:        if (i < 0)
        !           392:                goto ErrorReturn;
        !           393:        while (i--)             /* Any excess should be 0 */
        !           394:                if (*front++)
        !           395:                        goto ErrorReturn;
        !           396:        /* front now points to the data */
        !           397: 
        !           398:        /* How to distinguish old PGP from PKCS formats.
        !           399:         * The old PGP format ends in a trailing type byte, with
        !           400:         * all 1's padding before that.  The PKCS format ends in
        !           401:         * 16 bytes of message digest, preceded by an ASN string
        !           402:         * which is not all 1's.
        !           403:         */
        !           404:        if (back[-1] == MD_ENCRYPTED_BYTE &&
        !           405:            back[-17] == 0xff && back[-18] == 0xff) {
        !           406:                /* Old PGP format: Padding is at the end */
        !           407:                if (*--back != MD_ENCRYPTED_BYTE)
        !           408:                        goto ErrorReturn;
        !           409:                if (*front++ != MD5_ALGORITHM_BYTE) {
        !           410:                        mp_burn(temp);
        !           411:                        return -2;
        !           412:                }
        !           413:                while (*--back == 0xff) /* Skip constant padding */
        !           414:                        ;
        !           415:                if (*back)              /* It should end with a zero */
        !           416:                        goto ErrorReturn;
        !           417:        } else {
        !           418:                /* PKCS format: padding at the beginning */
        !           419:                if (*front++ != MD_ENCRYPTED_BYTE)
        !           420:                        goto ErrorReturn;
        !           421:                while (*front++ == 0xff) /* Skip constant padding */
        !           422:                        ;
        !           423:                if (front[-1])  /* First non-FF byte should be 0 */
        !           424:                        goto ErrorReturn;
        !           425:                /* Then comes the ASN header */
        !           426:                if (memcmp(front, asn_array, sizeof(asn_array))) {
        !           427:                        mp_burn(temp);
        !           428:                        return -2;
        !           429:                }
        !           430:                front += sizeof(asn_array);
        !           431: /* This is temporary - to be removed on release */
        !           432:                if (back-front == 17 && *front == MD5_ALGORITHM_BYTE) {
        !           433:                        front++;
        !           434:                        fprintf(stderr, "PGP 2.2b signature bug!\n");
        !           435:                }
        !           436:        }
        !           437: /* We're done - copy user data to outbuf */
        !           438:        if (back < front)
        !           439:                goto ErrorReturn;
        !           440:        memcpy(outbuf, front, back-front);
        !           441:        mp_burn(temp);
        !           442:        return back-front;
        !           443: ErrorReturn:
        !           444:        mp_burn(temp);
        !           445:        return -1;
        !           446: } /* rsa_public_decrypt */
        !           447: 
        !           448: /* We expect to find random padding and an encryption key */
        !           449: int
        !           450: rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
        !           451:         unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
        !           452: /* Decrypt an encryption key using a private key.  Returns the number of bytes
        !           453:  * extracted, or <0 on error.
        !           454:  * -1: Corrupted packet.
        !           455:  */
        !           456: {
        !           457: #ifdef RSAREF
        !           458:        R_RSA_PRIVATE_KEY PrivKey;
        !           459: #endif
        !           460:        unsigned int blocksize;
        !           461:        unit temp[MAX_UNIT_PRECISION];
        !           462:        unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
        !           463:        byte *front, *back;
        !           464:        int i;
        !           465: 
        !           466:        mp_move(temp,P);
        !           467:        mp_dec(temp);
        !           468:        mp_mod(DP,D,temp);
        !           469:        mp_move(temp,Q);
        !           470:        mp_dec(temp);
        !           471:        mp_mod(DQ,D,temp);
        !           472: 
        !           473: #ifdef RSAREF
        !           474:        make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
        !           475:        blocksize = countbytes(inbuf);
        !           476:        reg2rsaref((byte *)temp, blocksize, inbuf);
        !           477:        i = RSAPrivateBlock((byte *)temp, &blocksize,
        !           478:                            (byte *)temp, blocksize, &PrivKey);
        !           479:        if (i < 0)
        !           480:                goto ErrorReturn;
        !           481:        front = (byte *)temp;                   /* Start of block */
        !           482:        back = front + blocksize;               /* End of block */
        !           483:        i = blocksize - countbytes(N) + 1;      /* Expected # of leading 0's */
        !           484: #else
        !           485:        i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
        !           486:        if (i < 0)
        !           487:                goto ErrorReturn;
        !           488:        mp_convert_order((byte *)temp);
        !           489:        front = (byte *)temp;                   /* Start of block */
        !           490:        i = units2bytes(global_precision);
        !           491:        back = (byte *)front + i;               /* End of block */
        !           492:        blocksize = countbytes(N) - 1;
        !           493:        i -= blocksize;                         /* Expected # of leading 0's */
        !           494: #endif
        !           495:        if (i < 0)                              /* This shouldn't happen */
        !           496:                goto ErrorReturn;
        !           497:        while (i--)                             /* Extra bytes should be 0 */
        !           498:                if (*front++)
        !           499:                        goto ErrorReturn;
        !           500: 
        !           501:        /* How to distinguish old PGP from PKCS formats.
        !           502:         * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
        !           503:         * while PKCS formats have it leading.
        !           504:         */
        !           505:        if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
        !           506:                /* PGP 2.0 format  - padding at the end */
        !           507:                if (back[-1] != CK_ENCRYPTED_BYTE)
        !           508:                        goto ErrorReturn;
        !           509:                while (*--back) /* Skip non-zero random padding */
        !           510:                        ;
        !           511:        } else {
        !           512:                /* PKCS format - padding at the beginning */
        !           513:                if (*front++ != CK_ENCRYPTED_BYTE)
        !           514:                        goto ErrorReturn;
        !           515:                while (*front++)        /* Skip non-zero random padding */
        !           516:                        ;
        !           517:        }
        !           518:        if (back < front)
        !           519:                goto ErrorReturn;
        !           520:        memcpy(outbuf, front, back-front);
        !           521:        mp_burn(temp);
        !           522:        mp_burn(DP);
        !           523:        mp_burn(DQ);
        !           524:        return back-front;
        !           525: 
        !           526: ErrorReturn:
        !           527:        mp_burn(temp);
        !           528:        mp_burn(DP);
        !           529:        mp_burn(DQ);
        !           530:        return -1;
        !           531: } /* 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.