Beispiel #1
0
int rsa_wire2prikey(uint8_t *in, size_t inlen, RSA_KEY *key) {
	memset(key, 0, sizeof(RSA_KEY));

	key->bits = decbe64(in);
	size_t p_len = ((key->bits / 2) + 7) / 8;

	if(inlen < 8 + 2 * p_len + (key->bits + 7) / 8 + 8) {
		goto error;
	}

	if(os2ip(&key->p, &in[8], p_len) != 0) {
		goto error;
	}
	if(os2ip(&key->q, &in[8 + p_len], p_len) != 0) {
		goto error;
	}
	if(os2ip(&key->d, &in[8 + 2 * p_len], (key->bits + 7) / 8) != 0) {
		goto error;
	}

	key->e = decbe64(&in[p_len * 2 + (key->bits + 7) / 8 + 8]);

	if(bno_mul(&key->n, &key->p, &key->q) != 0) {
		goto error;
	}

	return 0;
error:
	memset(key, 0, sizeof(RSA_KEY));
	return 1;
}
Beispiel #2
0
int rsa_wire_prikey2pubkey(uint8_t *in, size_t inlen, uint8_t *out, size_t outlen) {
	uint64_t bits = decbe64(in);
	size_t p_len = ((bits / 2) + 7) / 8;
	int ret = 0;

	if(inlen < rsa_prikey_bufsize(bits) || outlen < rsa_pubkey_bufsize(bits)) {
		return -1;
	}

	bignum n = BN_ZERO, p = BN_ZERO, q = BN_ZERO;
	if(os2ip(&p, &in[8], p_len) != 0) {
		goto error;
	}
	if(os2ip(&q, &in[8+p_len], p_len) != 0) {
		goto error;
	}

	if(bno_mul(&n, &p, &q) != 0) {
		goto error;
	}

	memcpy(out, in, 8);
	i2osp(&out[8], (bits + 7) / 8, &n);
	memcpy(&out[rsa_pubkey_bufsize(bits) - 8],
		&in[rsa_prikey_bufsize(bits) - 8], 8);

	goto cleanup;

error:
	ret = 1;
cleanup:
	ret |= bnu_free(&n);
	ret |= bnu_free(&p);
	ret |= bnu_free(&q);

	return ret;
}
Beispiel #3
0
int rsa_wire2pubkey(uint8_t *in, size_t inlen, RSA_PUBLIC_KEY *key) {
	key->n = BN_ZERO;
	key->bits = decbe64(in);
	if(inlen < (key->bits + 7) / 8 + 8) {
		return 1;
	}

	if(os2ip(&key->n, &in[8], (key->bits + 7) / 8) != 0) {
		goto error;
	}

	key->e = decbe64(&in[8 + (key->bits + 7) / 8]);

	return 0;

error:
	memset(key, 0, sizeof(RSA_PUBLIC_KEY));
	return 1;
}
Beispiel #4
0
int mpbsetbin(mpbarrett* b, const byte* osdata, size_t ossize)
{
	int rc = -1;
	size_t size;
																				
	/* skip zero bytes */
	while (!(*osdata) && ossize)
	{
		osdata++;
		ossize--;
	}
																				
	size = MP_BYTES_TO_WORDS(ossize + MP_WBYTES - 1);
                                                                                
	if (b->modl)
	{
		if (b->size != size)
			b->modl = (mpw*) realloc(b->modl, (2*size+1) * sizeof(mpw));
	}
	else
		b->modl = (mpw*) malloc((2*size+1) * sizeof(mpw));

	if (b->modl)
	{
		register mpw* temp = (mpw*) malloc((6*size+4) * sizeof(mpw));

		b->size = size;
		b->mu = b->modl+size;

		rc = os2ip(b->modl, size, osdata, ossize);

		mpbmu_w(b, temp);

		free(temp);
	}

	return rc;
}
Beispiel #5
0
int rsa_pss_verify(RSA_PUBLIC_KEY *key, uint8_t *sig, size_t siglen, uint8_t *message, size_t mlen, int *valid) {
	if(key == NULL || sig == NULL || message == NULL || valid == NULL) {
		return -1;
	}

	const size_t emlen = (key->bits - 2) / 8 + 1;
	const size_t hlen = 32;
	const size_t slen = hlen;
	SHA256_CTX ctx;
	uint8_t hash[hlen];
	uint8_t zeroes[8];
	uint8_t *em = NULL;
	uint8_t *mask = NULL;
	bignum em_bn = BN_ZERO;
	bignum s_bn = BN_ZERO;

	int ret;

	*valid = 0;

	if((em = malloc(emlen)) == NULL) {
		return MALLOC_FAIL;
	}

	if((mask = malloc(emlen - hlen - 1)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	if((ret = os2ip(&s_bn, sig, siglen)) != 0) {
		/* cleanup is non-necessary here, but no harm */
		goto err;
	}

	if((ret = rsa_encrypt(key, &s_bn, &em_bn)) != 0) {
		goto err;
	}

	if((ret = i2osp(em, emlen, &em_bn)) != 0) {
		goto err;
	}

	mgf1_sha256(&em[emlen - hlen - 1], hlen, emlen - hlen - 1, mask);

	xor_bytes(em, mask, emlen - hlen - 1, em);

	sha256_init(&ctx);
	sha256_update(&ctx, message, mlen);
	sha256_final(&ctx, hash);

	memset(zeroes, 0x00, 8);

	sha256_init(&ctx);
	sha256_update(&ctx, zeroes, 8);
	sha256_update(&ctx, hash, hlen);
	sha256_update(&ctx, &em[emlen - hlen - slen - 1], slen);
	sha256_final(&ctx, hash);

	xor_bytes(&em[emlen - hlen - 1], hash, hlen, &em[emlen - hlen - 1]);
	em[emlen - hlen - slen - 2] ^= 0x01;
	em[emlen - 1] ^= 0xbc;
	em[0] &= ((uint8_t) 0xff) >> (emlen * 8 - (key->bits - 2));
	memset(&em[emlen - hlen - slen - 1], 0x00, slen);

	size_t i;
	uint8_t val = 0;
	for(i = 0; i < emlen; i++) {
		val |= (em[i]);
	}

	if(val) {
		*valid = 0;
	} else {
		*valid = 1;
	}

	ret = 0;

err:
	memsets(&ctx, 0x00, sizeof(SHA256_CTX));
	memsets(hash, 0x00, hlen);
	if(em) zfree(em, emlen);
	if(mask) zfree(mask, emlen - hlen - 1);
	bnu_free(&em_bn);
	bnu_free(&s_bn);

	return ret;
}
Beispiel #6
0
int rsa_pss_sign(RSA_KEY *key, uint8_t *message, size_t mlen, uint8_t *out, size_t outlen) {
	if(key == NULL || message == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t emlen = (key->bits - 2) / 8 + 1;
	const size_t hlen = 32;
	const size_t slen = hlen;
	SHA256_CTX ctx;
	uint8_t mhash[hlen];
	uint8_t salt[slen];
	uint8_t zeroes[8];
	uint8_t *em = NULL;
	bignum em_bn = BN_ZERO;
	bignum s_bn = BN_ZERO;

	int ret;

	if(outlen < k) {
		/* avoid buffer overflows */
		return TOO_SHORT;
	}

	if(emlen < hlen + slen + 2) {
		/* key too small to sign */
		return CRYPTOGRAPHY_ERROR;
	}

	/* allocate space for em */
	if((em = malloc(emlen)) == NULL) {
		return MALLOC_FAIL;
	}

	/* generate salt, as we can still exit without cleanup if this fails */
	if(cs_rand(salt, slen) != 0) {
		return CRYPTOGRAPHY_ERROR;
	}

	sha256_init(&ctx);
	sha256_update(&ctx, message, mlen);
	sha256_final(&ctx, mhash);

	/* calculate H = sha256(0x00 00 00 00 00 00 00 00 || mhash || salt) */
	memset(zeroes, 0x00, 8);

	sha256_init(&ctx);
	sha256_update(&ctx, zeroes, 8);
	sha256_update(&ctx, mhash, hlen);
	sha256_update(&ctx, salt, slen);
	sha256_final(&ctx, &em[emlen - hlen - 1]);

	mgf1_sha256(&em[emlen - hlen - 1], hlen, emlen - hlen - 1, em);

	/* xor in 0x01 and salt */
	em[emlen - slen - hlen - 2] ^= 0x01;
	xor_bytes(&em[emlen - slen - hlen - 1], salt, slen, &em[emlen - slen - hlen - 1]);
	em[emlen - 1] = 0xbc;

	em[0] &= ((uint8_t) 0xff) >> (8 * emlen - (key->bits - 2));

	if((ret = os2ip(&em_bn, em, emlen)) != 0) {
		goto err;
	}

	if((ret = rsa_decrypt(key, &em_bn, &s_bn)) != 0) {
		goto err;
	}

	if((ret = i2osp(out, outlen, &s_bn)) != 0) {
		goto err;
	}

	ret = 0;
err:
	memsets(mhash, 0, hlen);
	memsets(salt, 0, slen);
	memsets(&ctx, 0, sizeof(SHA256_CTX));
	bnu_free(&s_bn);
	bnu_free(&em_bn);
	if(em) zfree(em, emlen);

	return ret;
}
Beispiel #7
0
int rsa_oaep_decrypt(RSA_KEY *key, uint8_t *ctext, size_t clen, uint8_t *out, size_t outlen) {
	if(key == NULL || ctext == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t hlen = 32;
	bignum c_bn = BN_ZERO;
	bignum m_bn = BN_ZERO;
	uint8_t *em = NULL;
	uint8_t *db = NULL;
	uint8_t *mask = NULL;
	uint8_t seed[hlen];
	size_t message_start;

	int ret;

	/* nothing critical yet */
	if((ret = os2ip(&c_bn, ctext, clen)) != 0) {
		return ret;
	}

	/* now sensitive information is contained in our buffers, so we have
	 * to clean up */
	if((ret = rsa_decrypt(key, &c_bn, &m_bn)) != 0) {
		goto err;
	}

	if((em = malloc(k)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	if((ret = i2osp(em, k, &m_bn)) != 0) {
		goto err;
	}
	db = em + hlen + 1;

	if((mask = malloc(k - hlen - 1)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	/* calculate seed mask = MGF1(maskedDB, k - hlen - 1) */
	mgf1_sha256(db, k - hlen - 1, hlen, mask);

	/* calculate seed */
	xor_bytes(em + 1, mask, hlen, seed);

	/* calculate dbMask */
	mgf1_sha256(seed, hlen, k - hlen - 1, mask);

	/* unmask db */
	xor_bytes(db, mask, k - hlen - 1, db);

	/* find the start of the message */
	for(message_start = hlen; message_start < k - hlen - 1 &&
		db[message_start] == 0x00; message_start++) {}

	uint8_t valid = 0;
	valid |= memcmp_ct(db, lhash, 32);
	valid |= em[0];
	valid |= !(message_start != k - hlen - 1 && db[message_start] == 1);

	/* if valid is non-zero this is not a valid message */
	if(valid != 0) {
		ret = CRYPTOGRAPHY_ERROR;
		goto err;
	}

	message_start++;

	/* prevent buffer overflows */
	if(outlen < k - hlen - 1 - message_start) {
		ret = TOO_SHORT;
		goto err;
	}
	memcpy(out, &db[message_start], k - hlen - 1 - message_start);

	ret = 0;
err:
	ret = ret == 0 ? bnu_free(&c_bn) : ret;
	ret = ret == 0 ? bnu_free(&m_bn) : ret;
	if(em) zfree(em, k);
	if(mask) zfree(mask, k - hlen - 1);
	memsets(seed, 0x00, hlen);

	return ret;
}
Beispiel #8
0
int rsa_oaep_encrypt(RSA_PUBLIC_KEY *key, uint8_t *message, size_t mlen, uint8_t *out, size_t outlen) {
	if(key == NULL || message == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t hlen = 32;
	uint8_t seed[hlen];
	uint8_t *mask;
	uint8_t *em;
	uint8_t *db;
	bignum m_bn;
	bignum c_bn;

	int ret;

	/* message is too long to encrypt */
	if(k - 2 * hlen - 2 < mlen) {
		return TOO_LONG;
	}

	/* output buffer is too small */
	if(outlen < k) {
		return TOO_SHORT;
	}

	/* do stuff involving the masks first, as in case of error it does not
	 * need to be kept secure */
	if(cs_rand(seed, hlen) != 0) {
		return CRYPTOGRAPHY_ERROR;
	}

	if((mask = malloc(k - hlen - 1)) == NULL) {
		return MALLOC_FAIL;
	}

	/* calculate dbMask = MGF(seed, k - hLen - 1) */
	mgf1_sha256(seed, hlen, k - hlen - 1, mask);

	/* now initialize the string to be encrypted */
	if((em = malloc(k)) == NULL) {
		return MALLOC_FAIL;
	}

	/* from now on we have to clean up memory after any failures */
	/* em[hlen:] is all DB = lhash || PS || 0x01 || M */
	db = em + hlen + 1;
	memcpy(db, lhash, hlen);
	/* PS is a padding string of zeroes */
	memset(db + hlen, 0x00, k - 2 * hlen - mlen - 2);
	/* there is then one byte of value 0x01 */
	db[k - 2 - hlen - mlen] = 0x01;
	/* then message */
	memcpy(&db[k - hlen - 1 - mlen], message, mlen);

	/* now apply the mask to it */
	xor_bytes(db, mask, k - hlen - 1, db);

	/* now we can repurpose mask to encode the seed mask */
	mgf1_sha256(db, k - hlen - 1, hlen, mask);
	/* xor it into em */
	xor_bytes(seed, mask, hlen, em + 1);

	em[0] = 0x00;

	m_bn = BN_ZERO;
	c_bn = BN_ZERO;
	/* now convert to a big integer */
	if((ret = os2ip(&m_bn, em, k)) != 0) {
		goto err;
	}

	/* encrypt */
	if((ret = rsa_encrypt(key, &m_bn, &c_bn)) != 0) {
		goto err;
	}

	/* convert back */
	if((ret = i2osp(out, outlen, &c_bn)) != 0) {
		goto err;
	}

	/* encryption is officially done, clean up */
	ret = 0;

err:
	/* free mask and em, zero seed */
	zfree(mask, k - hlen - 1);
	zfree(em, k - 1);
	memsets(seed, 0x00, hlen);

	/* free the bignums */
	/* an error here is still an error as it is a possible leak of
	 * sensitive data */
	ret = ret == 0 ? bnu_free(&m_bn) : ret;
	ret = ret == 0 ? bnu_free(&c_bn) : ret;

	return ret;
}