Пример #1
0
int
rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
	 unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
/* Encrypt a message digest with a private key.
 * Returns <0 on error:
 * -1: generic error
 * -4: Key too big
 * -5: Key too small
 */
{
	unit temp[MAX_UNIT_PRECISION];
	unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
	byte *p;
	int i;
	unsigned int blocksize;

	/* PGP doesn't store these coefficents, so we need to compute them. */
	mp_move(temp,P);
	mp_dec(temp);
	mp_mod(DP,D,temp);
	mp_move(temp,Q);
	mp_dec(temp);
	mp_mod(DQ,D,temp);

	p = (byte *)temp;


	/* We are building the mpi in place, except for a possible
	 * byte-order swap to little-endian at the end.  Thus, we
	 * need to fill the buffer with leading 0's in the unused
	 * most significant byte positions.
	 */
	blocksize = countbytes(N) - 1;	/* Space available for data */
	for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
		*p++ = 0;

	i = blocksize - 2 - bytes;		/* Padding needed */
	i -= sizeof(asn_array);		/* Space for type encoding */
	if (i < 0) {
		i = -4;			/* Error code */
		goto Cleanup;
	}
	*p++ = MD_ENCRYPTED_BYTE;	/* Type byte */
	memset(p, ~0, i);		/* All 1's padding */
	p += i;
	*p++ = 0;			/* Zero framing byte */
	memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
	p += sizeof(asn_array);
	memcpy(p, inbuf, bytes);	/* User data */

	mp_convert_order((byte *)temp);
	i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U);	/* Encrypt */
	if (i < 0)
		i = -1;

Cleanup:
	burn(temp);

	return i;
} /* rsa_private_encrypt */
Пример #2
0
static int
testsimpel(void)
{
	const char str42[] = "2a";
	MINT *t2;
	char *s;

	mp_madd(c42, c1, t0);
	testmcmp(c43, t0, "madd0");
	mp_madd(t0, c1, t0);
	testmcmp(c44, t0, "madd1");
	mp_msub(t0, c1, t0);
	testmcmp(c43, t0, "msub0");
	mp_msub(t0, c1, t0);
	testmcmp(c42, t0, "msub1");
	mp_move(c42, t0);
	testmcmp(c42, t0, "move0");

	t2 = mp_xtom(str42);
	testmcmp(c42, t2, "xtom");
	s = mp_mtox(t2);
	if (strcmp(str42, s) == 0)
		printf("ok %d - %s\n", ++tnr, "mtox0");
	else
		printf("not ok %d - %s\n", ++tnr, "mtox0");
	mp_mfree(t2);
}
Пример #3
0
/* Converts a possibly-signed digit string into a large binary number.
   Returns assumed radix, derived from suffix 'h','o',b','.' */
int str2reg(unitptr reg, string digitstr)
{
    unit temp[MAX_UNIT_PRECISION], base[MAX_UNIT_PRECISION];
    int c, i;
    boolean minus = FALSE;
    short radix;		/* base 2-16 */

    mp_init(reg, 0);

    i = string_length(digitstr);
    if (i == 0)
	return (10);		/* empty string, assume radix 10 */
    c = digitstr[i - 1];	/* get last char in string */

    switch (c) {		/* classify radix select suffix character */
    case '.':
	radix = 10;
	break;
    case 'H':
    case 'h':
	radix = 16;
	break;
    case 'O':
    case 'o':
	radix = 8;
	break;
    case 'B':			/* caution! 'b' is a hex digit! */
    case 'b':
	radix = 2;
	break;
    default:
	radix = 10;
	break;
    }

    mp_init(base, radix);
    if ((minus = (*digitstr == '-')) != 0)
	digitstr++;
    while ((c = *digitstr++) != 0) {
	if (c == ',')
	    continue;		/* allow commas in number */
	c = ctox(c);
	if ((c < 0) || (c >= radix))
	    break;		/* scan terminated by any non-digit */
	mp_mult(temp, reg, base);
	mp_move(reg, temp);
	mp_init(temp, c);
	mp_add(reg, temp);
    }
    if (minus)
	mp_neg(reg);
    return (radix);
}				/* str2reg */
Пример #4
0
/* We expect to find random padding and an encryption key */
int
rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
	 unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
/* Decrypt an encryption key using a private key.  Returns the number of bytes
 * extracted, or <0 on error.
 * -1: Generic error
 * -3: Key too big
 * -4: Key too small
 * -5: Maybe malformed RSA
 * -7: Unknown conventional algorithm
 * -9: Malformed RSA packet
 */
{
	byte *back;
	byte *front;
	unsigned int blocksize;
	unit temp[MAX_UNIT_PRECISION];
	unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
	int i;

	/* PGP doesn't store (d mod p-1) and (d mod q-1), so compute 'em */
	mp_move(temp,P);
	mp_dec(temp);
	mp_mod(DP,D,temp);
	mp_move(temp,Q);
	mp_dec(temp);
	mp_mod(DQ,D,temp);

	i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
	mp_burn(DP);
	mp_burn(DQ);
	if (i < 0) {
		mp_burn(temp);
		return -1;
	}
	mp_convert_order((byte *)temp);
	front = (byte *)temp;			/* Start of block */
	i = units2bytes(global_precision);
	back = (byte *)front + i;		/* End of block */
	blocksize = countbytes(N) - 1;
	i -= blocksize;				/* Expected # of leading 0's */

	if (i < 0)				/* This shouldn't happen */
		goto Corrupted;
	while (i--)				/* Extra bytes should be 0 */
		if (*front++)
			goto Corrupted;

	/* How to distinguish old PGP from PKCS formats.
	 * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
	 * while PKCS formats have it leading.
	 */
	if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
		/* PGP 2.0 format  - padding at the end */
		if (back[-1] != CK_ENCRYPTED_BYTE)
			goto Corrupted;
		while (*--back)	/* Skip non-zero random padding */
			;
	} else {
		/* PKCS format - padding at the beginning */
		if (*front++ != CK_ENCRYPTED_BYTE)
			goto Corrupted;
		while (*front++)	/* Skip non-zero random padding */
			;
	}
	if (back <= front)
		goto Corrupted;
	blocksize = back-front;

	memcpy(outbuf, front, blocksize);
	mp_burn(temp);
	return blocksize;

Corrupted:
	mp_burn(temp);
	return -9;
} /* rsa_private_decrypt */