示例#1
0
void md_hmac(uint8_t *mac, const uint8_t *in, int in_len, const uint8_t *key,
    int key_len) {
#if MD_MAP == SHONE || MD_MAP == SH224 || MD_MAP == SH256 || MD_MAP == BLAKE2S_160 || MD_MAP == BLAKE2S_256
  #define block_size 64
#elif MD_MAP == SH384 || MD_MAP == SH512
  #define block_size  128
#endif
    uint8_t opad[block_size + RLC_MD_LEN];
    uint8_t *ipad = RLC_ALLOCA(uint8_t, block_size + in_len);
	uint8_t _key[RLC_MAX(RLC_MD_LEN, block_size)];

	if (key_len > block_size) {
		md_map(_key, key, key_len);
		key = _key;
		key_len = RLC_MD_LEN;
	}
	if (key_len <= block_size) {
		memcpy(_key, key, key_len);
		memset(_key + key_len, 0, block_size - key_len);
		key = _key;
	}
	for (int i = 0; i < block_size; i++) {
		opad[i] = 0x5C ^ key[i];
		ipad[i] = 0x36 ^ key[i];
	}
	memcpy(ipad + block_size, in, in_len);
	md_map(opad + block_size, ipad, block_size + in_len);
	md_map(mac, opad, block_size + RLC_MD_LEN);
}
示例#2
0
int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) {
	bn_t n, k, x, r;
	ec_t p;
	uint8_t hash[MD_LEN];
	uint8_t m[len + FC_BYTES];
	int result = STS_OK;

	bn_null(n);
	bn_null(k);
	bn_null(x);
	bn_null(r);
	ec_null(p);

	TRY {
		bn_new(n);
		bn_new(k);
		bn_new(x);
		bn_new(r);
		ec_new(p);

		ec_curve_get_ord(n);
		do {
			bn_rand_mod(k, n);
			ec_mul_gen(p, k);
			ec_get_x(x, p);
			bn_mod(r, x, n);
		} while (bn_is_zero(r));

		memcpy(m, msg, len);
		bn_write_bin(m + len, FC_BYTES, r);
		md_map(hash, m, len + FC_BYTES);

		if (8 * MD_LEN > bn_bits(n)) {
			len = CEIL(bn_bits(n), 8);
			bn_read_bin(e, hash, len);
			bn_rsh(e, e, 8 * MD_LEN - bn_bits(n));
		} else {
			bn_read_bin(e, hash, MD_LEN);
		}

		bn_mod(e, e, n);

		bn_mul(s, d, e);
		bn_mod(s, s, n);
		bn_sub(s, n, s);
		bn_add(s, s, k);
		bn_mod(s, s, n);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(n);
		bn_free(k);
		bn_free(x);
		bn_free(r);
		ec_free(p);
	}
	return result;
}
示例#3
0
void ep2_map(ep2_t p, uint8_t *msg, int len) {
	bn_t x;
	fp2_t t0;
	uint8_t digest[MD_LEN];

	bn_null(x);
	fp2_null(t0);

	TRY {
		bn_new(x);
		fp2_new(t0);

		md_map(digest, msg, len);
		bn_read_bin(x, digest, MIN(FP_BYTES, MD_LEN));

		fp_prime_conv(p->x[0], x);
		fp_zero(p->x[1]);
		fp_set_dig(p->z[0], 1);
		fp_zero(p->z[1]);

		while (1) {
			ep2_rhs(t0, p);

			if (fp2_srt(p->y, t0)) {
				p->norm = 1;
				break;
			}

			fp_add_dig(p->x[0], p->x[0], 1);
		}

		switch (ep_param_get()) {
			case BN_P158:
			case BN_P254:
			case BN_P256:
			case BN_P638:
				ep2_mul_cof_bn(p, p);
				break;
			case B12_P638:
				ep2_mul_cof_b12(p, p);
				break;
			default:
				/* Now, multiply by cofactor to get the correct group. */
				ep2_curve_get_cof(x);
				if (bn_bits(x) < BN_DIGIT) {
					ep2_mul_dig(p, p, x->dp[0]);
				} else {
					ep2_mul(p, p, x);
				}
				break;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(x);
		fp2_free(t0);
	}
}
示例#4
0
文件: relic_cp_bbs.c 项目: ace0/relic
int cp_bbs_ver(g1_t s, uint8_t *msg, int len, int hash, g2_t q, gt_t z) {
	bn_t m, n;
	g2_t g;
	gt_t e;
	uint8_t h[MD_LEN];
	int result = 0;

	bn_null(m);
	bn_null(n);
	g2_null(g);
	gt_null(e);

	TRY {
		bn_new(m);
		bn_new(n);
		g2_new(g);
		gt_new(e);

		g2_get_ord(n);

		/* m = H(msg). */
		if (hash) {
			bn_read_bin(m, msg, len);
		} else {
			md_map(h, msg, len);
			bn_read_bin(m, h, MD_LEN);
		}
		bn_mod(m, m, n);

		g2_mul_gen(g, m);
		g2_add(g, g, q);
		g2_norm(g, g);

		pc_map(e, s, g);

		if (gt_cmp(e, z) == CMP_EQ) {
			result = 1;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(n);
		g2_free(g);
		gt_free(e);
	}
	return result;
}
示例#5
0
/**
 * Generates pseudo-random bytes by iterating the hash function.
 *
 * @param[out] out 			- the buffer to write.
 * @param[in] out_len		- the number of bytes to write.
 */
static void rand_gen(uint8_t *out, int out_len) {
	int m = CEIL(out_len, MD_LEN);
	uint8_t hash[MD_LEN], data[(RAND_SIZE - 1)/2];
	ctx_t *ctx = core_get();

	/* data = V */
	memcpy(data, ctx->rand + 1, (RAND_SIZE - 1)/2);
	for (int i = 0; i < m; i++) {
		/* w_i = Hash(data) */
		md_map(hash, data, sizeof(data));
		/* W = W || w_i */
		memcpy(out, hash, MIN(MD_LEN, out_len));
		out += MD_LEN;
		out_len -= MD_LEN;
		/* data = data + 1 mod 2^b. */
		rand_inc(data, (RAND_SIZE - 1)/2, 1);
	}
}
示例#6
0
void md_kdf2(uint8_t *key, int key_len, const uint8_t *in,
		int in_len) {
	uint32_t i, j, d;
	uint8_t buffer[in_len + sizeof(uint32_t)];
	uint8_t t[key_len + MD_LEN];

	/* d = ceil(kLen/hLen). */
	d = CEIL(key_len, MD_LEN);
	memcpy(buffer, in, in_len);
	for (i = 1; i <= d; i++) {
		j = util_conv_big(i);
		/* c = integer_to_string(c, 4). */
		memcpy(buffer + in_len, &j, sizeof(uint32_t));
		/* t = t || hash(z || c). */
		md_map(t + (i - 1) * MD_LEN, buffer, in_len + sizeof(uint32_t));
	}
	memcpy(key, t, key_len);
}
示例#7
0
文件: relic_cp_bbs.c 项目: ace0/relic
int cp_bbs_sig(g1_t s, uint8_t *msg, int len, int hash, bn_t d) {
	bn_t m, n, r;
	uint8_t h[MD_LEN];
	int result = STS_OK;

	bn_null(m);
	bn_null(n);
	bn_null(r);

	TRY {
		bn_new(m);
		bn_new(n);
		bn_new(r);

		g1_get_ord(n);

		/* m = H(msg). */
		if (hash) {
			bn_read_bin(m, msg, len);
		} else {
			md_map(h, msg, len);
			bn_read_bin(m, h, MD_LEN);
		}
		bn_mod(m, m, n);

		/* m = 1/(m + d) mod n. */
		bn_add(m, m, d);
		bn_gcd_ext(r, m, NULL, m, n);
		if (bn_sign(m) == BN_NEG) {
			bn_add(m, m, n);
		}
		/* s = 1/(m+d) * g1. */
		g1_mul_gen(s, m);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(n);
		bn_free(r);
	}
	return result;
}
示例#8
0
/*
 * Computes the hash derivation function.
 *
 * param[out] out       - the result.
 * param[in] out_len    - the number of bytes to return.
 * param[in] in         - the input string.
 * param[in] in_len     - the number of bytes in the input.
 */
static void rand_hash(uint8_t *out, int out_len, uint8_t *in,
		int in_len) {
	uint32_t j = util_conv_big(8 * out_len);
	int len = CEIL(out_len, MD_LEN);
	uint8_t buf[1 + sizeof(uint32_t) + in_len], hash[MD_LEN];

	buf[0] = 1;
	memcpy(buf + 1, &j, sizeof(uint32_t));
	memcpy(buf + 1 + sizeof(uint32_t), in, in_len);

	for (int i = 0; i < len; i++) {
		/* h = Hash(counter || bits_to_return || input_string) */
		md_map(hash, buf, 1 + sizeof(uint32_t) + in_len);
		/* temp = temp || h */
		memcpy(out, hash, MIN(MD_LEN, out_len));
		out += MD_LEN;
		out_len -= MD_LEN;
		/* counter = counter + 1 */
		buf[0]++;
	}
}
示例#9
0
void rand_bytes(uint8_t *buf, int size) {
	uint8_t hash[MD_LEN];
	int carry, len  = (RAND_SIZE - 1)/2;
	ctx_t *ctx = core_get();

	if (sizeof(int) > 2 && size > (1 << 16)) {
		THROW(ERR_NO_VALID);
	}

	/* buf = hash_gen(size) */
	rand_gen(buf, size);
	/* H = hash(03 || V) */
	ctx->rand[0] = 0x3;
	md_map(hash, ctx->rand, 1 + len);
	/* V = V + H + C  + reseed_counter. */
	rand_add(ctx->rand + 1, ctx->rand + 1 + len, len);
	carry = rand_add(ctx->rand + 1 + (len - MD_LEN), hash, MD_LEN);
	rand_inc(ctx->rand, len - MD_LEN + 1, carry);
	rand_inc(ctx->rand, len + 1, ctx->counter);
	ctx->counter = ctx->counter + 1;
}
示例#10
0
int cp_rsa_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t pub) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	bn_null(m);
	bn_null(eb);

	size = bn_size_bin(pub->n);

	if (pub == NULL || in_len <= 0 || in_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#endif
			bn_read_bin(m, in, in_len);
			bn_add(eb, eb, m);

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC_FIN);
#endif
			bn_mxp(eb, eb, pub->e, pub->n);

			if (size <= *out_len) {
				*out_len = size;
				memset(out, 0, *out_len);
				bn_write_bin(out, size, eb);
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#if CP_RSA == BASIC || !defined(STRIP)

int cp_rsa_dec_basic(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	size = bn_size_bin(prv->n);

	if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) {
		return STS_ERR;
	}

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, in, in_len);
		bn_mxp(eb, eb, prv->d, prv->n);

		if (bn_cmp(eb, prv->n) != CMP_LT) {
			result = STS_ERR;
		}
#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#endif
			size = size - pad_len;

			if (size <= *out_len) {
				memset(out, 0, size);
				bn_write_bin(out, size, eb);
				*out_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == QUICK || !defined(STRIP)

int cp_rsa_dec_quick(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	bn_null(m);
	bn_null(eb);

	size = bn_size_bin(prv->n);

	if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) {
		return STS_ERR;
	}

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, in, in_len);

		bn_copy(m, eb);

		/* m1 = c^dP mod p. */
		bn_mxp(eb, eb, prv->dp, prv->p);

		/* m2 = c^dQ mod q. */
		bn_mxp(m, m, prv->dq, prv->q);

		/* m1 = m1 - m2 mod p. */
		bn_sub(eb, eb, m);
		while (bn_sign(eb) == BN_NEG) {
			bn_add(eb, eb, prv->p);
		}
		bn_mod(eb, eb, prv->p);
		/* m1 = qInv(m1 - m2) mod p. */
		bn_mul(eb, eb, prv->qi);
		bn_mod(eb, eb, prv->p);
		/* m = m2 + m1 * q. */
		bn_mul(eb, eb, prv->q);
		bn_add(eb, eb, m);

		if (bn_cmp(eb, prv->n) != CMP_LT) {
			result = STS_ERR;
		}
#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#endif
			size = size - pad_len;

			if (size <= *out_len) {
				memset(out, 0, size);
				bn_write_bin(out, size, eb);
				*out_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == BASIC || !defined(STRIP)

int cp_rsa_sig_basic(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;
	uint8_t h[MD_LEN];

	if (prv == NULL || msg_len < 0) {
		return STS_ERR;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(prv->n) - 1;
	size = (size / 8) + (size % 8 > 0);
	if (pad_len > (size - 2)) {
		return STS_ERR;
	}
#else
	size = bn_size_bin(prv->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

		int operation = (!hash ? RSA_SIG : RSA_SIG_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#endif
			if (!hash) {
				md_map(h, msg, msg_len);
				bn_read_bin(m, h, MD_LEN);
				bn_add(eb, eb, m);
			} else {
				bn_read_bin(m, msg, msg_len);
				bn_add(eb, eb, m);
			}

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN);
#endif

			bn_mxp(eb, eb, prv->d, prv->n);

			size = bn_size_bin(prv->n);

			if (size <= *sig_len) {
				memset(sig, 0, size);
				bn_write_bin(sig, size, eb);
				*sig_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == QUICK || !defined(STRIP)

int cp_rsa_sig_quick(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) {
	bn_t m, eb;
	int pad_len, size, result = STS_OK;
	uint8_t h[MD_LEN];

	if (prv == NULL || msg_len < 0) {
		return STS_ERR;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(prv->n) - 1;
	size = (size / 8) + (size % 8 > 0);
	if (pad_len > (size - 2)) {
		return STS_ERR;
	}
#else
	size = bn_size_bin(prv->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

		int operation = (!hash ? RSA_SIG : RSA_SIG_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#endif
			if (!hash) {
				md_map(h, msg, msg_len);
				bn_read_bin(m, h, MD_LEN);
				bn_add(eb, eb, m);
			} else {
				bn_read_bin(m, msg, msg_len);
				bn_add(eb, eb, m);
			}

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN);
#endif

			bn_copy(m, eb);

			/* m1 = c^dP mod p. */
			bn_mxp(eb, eb, prv->dp, prv->p);

			/* m2 = c^dQ mod q. */
			bn_mxp(m, m, prv->dq, prv->q);

			/* m1 = m1 - m2 mod p. */
			bn_sub(eb, eb, m);
			while (bn_sign(eb) == BN_NEG) {
				bn_add(eb, eb, prv->p);
			}
			bn_mod(eb, eb, prv->p);
			/* m1 = qInv(m1 - m2) mod p. */
			bn_mul(eb, eb, prv->qi);
			bn_mod(eb, eb, prv->p);
			/* m = m2 + m1 * q. */
			bn_mul(eb, eb, prv->q);
			bn_add(eb, eb, m);
			bn_mod(eb, eb, prv->n);

			size = bn_size_bin(prv->n);

			if (size <= *sig_len) {
				memset(sig, 0, size);
				bn_write_bin(sig, size, eb);
				*sig_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

int cp_rsa_ver(uint8_t *sig, int sig_len, uint8_t *msg, int msg_len, int hash, rsa_t pub) {
	bn_t m, eb;
	int size, pad_len, result;
	uint8_t h1[MAX(msg_len, MD_LEN) + 8], h2[MAX(msg_len, MD_LEN)];

	/* We suppose that the signature is invalid. */
	result = 0;

	if (pub == NULL || msg_len < 0) {
		return 0;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(pub->n) - 1;
	if (size % 8 == 0) {
		size = size / 8 - 1;
	} else {
		size = bn_size_bin(pub->n);
	}
	if (pad_len > (size - 2)) {
		return 0;
	}
#else
	size = bn_size_bin(pub->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return 0;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, sig, sig_len);

		bn_mxp(eb, eb, pub->e, pub->n);

		int operation = (!hash ? RSA_VER : RSA_VER_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, MD_LEN, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, MD_LEN, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, bn_bits(pub->n), size, operation) == STS_OK) {
#endif

#if CP_RSAPD == PKCS2
			memset(h1, 0, 8);

			if (!hash) {
				md_map(h1 + 8, msg, msg_len);
				md_map(h2, h1, MD_LEN + 8);

				memset(h1, 0, MD_LEN);
				bn_write_bin(h1, size - pad_len, eb);
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, MD_LEN);
			} else {
				memcpy(h1 + 8, msg, msg_len);
				md_map(h2, h1, MD_LEN + 8);

				memset(h1, 0, msg_len);
				bn_write_bin(h1, size - pad_len, eb);

				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, msg_len);
			}
#else
			memset(h1, 0, MAX(msg_len, MD_LEN));
			bn_write_bin(h1, size - pad_len, eb);

			if (!hash) {
				md_map(h2, msg, msg_len);
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, MD_LEN);
			} else {
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, msg, msg_len);
			}
#endif
			result = (result == CMP_EQ ? 1 : 0);
		} else {
			result = 0;
		}
	}
	CATCH_ANY {
		result = 0;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}
示例#11
0
/**
 * Applies or removes a PKCS#1 v2.1 encryption padding.
 *
 * @param[out] m		- the buffer to pad.
 * @param[out] p_len	- the number of added pad bytes.
 * @param[in] m_len		- the message length in bytes.
 * @param[in] k_len		- the key length in bytes.
 * @param[in] operation	- flag to indicate the operation type.
 * @return STS_ERR if errors occurred, STS_OK otherwise.
 */
static int pad_pkcs2(bn_t m, int *p_len, int m_len, int k_len, int operation) {
	uint8_t pad, h1[MD_LEN], h2[MD_LEN], mask[k_len];
	int result = STS_OK;
	bn_t t;

	bn_null(t);

	TRY {
		bn_new(t);

		switch (operation) {
			case RSA_ENC:
				/* DB = lHash | PS | 01 | D. */
				md_map(h1, NULL, 0);
				bn_read_bin(m, h1, MD_LEN);
				*p_len = k_len - 2 * MD_LEN - 2 - m_len;
				bn_lsh(m, m, *p_len * 8);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, 0x01);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_ENC_FIN:
				/* EB = 00 | maskedSeed | maskedDB. */
				rand_bytes(h1, MD_LEN);
				md_mgf1(mask, k_len - MD_LEN - 1, h1, MD_LEN);
				bn_read_bin(t, mask, k_len - MD_LEN - 1);
				for (int i = 0; i < t->used; i++) {
					m->dp[i] ^= t->dp[i];
				}
				bn_write_bin(mask, k_len - MD_LEN - 1, m);
				md_mgf1(h2, MD_LEN, mask, k_len - MD_LEN - 1);
				for (int i = 0; i < MD_LEN; i++) {
					h1[i] ^= h2[i];
				}
				bn_read_bin(t, h1, MD_LEN);
				bn_lsh(t, t, 8 * (k_len - MD_LEN - 1));
				bn_add(t, t, m);
				bn_copy(m, t);
				break;
			case RSA_DEC:
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = STS_ERR;
				}
				m_len -= MD_LEN;
				bn_rsh(t, m, 8 * m_len);
				bn_write_bin(h1, MD_LEN, t);
				bn_mod_2b(m, m, 8 * m_len);
				bn_write_bin(mask, m_len, m);
				md_mgf1(h2, MD_LEN, mask, m_len);
				for (int i = 0; i < MD_LEN; i++) {
					h1[i] ^= h2[i];
				}
				md_mgf1(mask, k_len - MD_LEN - 1, h1, MD_LEN);
				bn_read_bin(t, mask, k_len - MD_LEN - 1);
				for (int i = 0; i < t->used; i++) {
					m->dp[i] ^= t->dp[i];
				}
				m_len -= MD_LEN;
				bn_rsh(t, m, 8 * m_len);
				bn_write_bin(h2, MD_LEN, t);
				md_map(h1, NULL, 0);
				pad = 0;
				for (int i = 0; i < MD_LEN; i++) {
					pad |= h1[i] - h2[i];
				}
				if (result == STS_OK) {
					result = (pad ? STS_ERR : STS_OK);
				}
				bn_mod_2b(m, m, 8 * m_len);
				*p_len = bn_size_bin(m);
				(*p_len)--;
				bn_rsh(t, m, *p_len * 8);
				if (bn_cmp_dig(t, 1) != CMP_EQ) {
					result = STS_ERR;
				}
				bn_mod_2b(m, m, *p_len * 8);
				*p_len = k_len - *p_len;
				break;
			case RSA_SIG:
			case RSA_SIG_HASH:
				/* M' = 00 00 00 00 00 00 00 00 | H(M). */
				bn_zero(m);
				bn_lsh(m, m, 64);
				/* Make room for the real message. */
				bn_lsh(m, m, MD_LEN * 8);
				break;
			case RSA_SIG_FIN:
				memset(mask, 0, 8);
				bn_write_bin(mask + 8, MD_LEN, m);
				md_map(h1, mask, MD_LEN + 8);
				bn_read_bin(m, h1, MD_LEN);
				md_mgf1(mask, k_len - MD_LEN - 1, h1, MD_LEN);
				bn_read_bin(t, mask, k_len - MD_LEN - 1);
				t->dp[0] ^= 0x01;
				/* m_len is now the size in bits of the modulus. */
				bn_lsh(t, t, 8 * MD_LEN);
				bn_add(m, t, m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PSS);
				for (int i = m_len - 1; i < 8 * k_len; i++) {
					bn_set_bit(m, i, 0);
				}
				break;
			case RSA_VER:
			case RSA_VER_HASH:
				bn_mod_2b(t, m, 8);
				if (bn_cmp_dig(t, RSA_PSS) != CMP_EQ) {
					result = STS_ERR;
				} else {
					for (int i = m_len; i < 8 * k_len; i++) {
						if (bn_get_bit(m, i) != 0) {
							result = STS_ERR;
						}
					}
					bn_rsh(m, m, 8);
					bn_mod_2b(t, m, 8 * MD_LEN);
					bn_write_bin(h2, MD_LEN, t);
					bn_rsh(m, m, 8 * MD_LEN);
					bn_write_bin(h1, MD_LEN, t);
					md_mgf1(mask, k_len - MD_LEN - 1, h1, MD_LEN);
					bn_read_bin(t, mask, k_len - MD_LEN - 1);
					for (int i = 0; i < t->used; i++) {
						m->dp[i] ^= t->dp[i];
					}
					m->dp[0] ^= 0x01;
					for (int i = m_len - 1; i < 8 * k_len; i++) {
						bn_set_bit(m, i - ((MD_LEN + 1) * 8), 0);
					}
					if (!bn_is_zero(m)) {
						result = STS_ERR;
					}
					bn_read_bin(m, h2, MD_LEN);
					*p_len = k_len - MD_LEN;
				}
				break;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(t);
	}

	return result;
}
示例#12
0
int cp_ecss_ver(bn_t e, bn_t s, uint8_t *msg, int len, ec_t q) {
	bn_t n, ev, rv;
	ec_t p;
	uint8_t hash[MD_LEN];
	uint8_t m[len + FC_BYTES];
	int result = 0;

	bn_null(n);
	bn_null(ev);
	bn_null(rv);
	ec_null(p);

	TRY {
		bn_new(n);
		bn_new(ev);
		bn_new(rv);
		ec_new(p);

		ec_curve_get_ord(n);

		if (bn_sign(e) == BN_POS && bn_sign(s) == BN_POS && !bn_is_zero(s)) {
			if (bn_cmp(e, n) == CMP_LT && bn_cmp(s, n) == CMP_LT) {
				ec_mul_sim_gen(p, s, q, e);
				ec_get_x(rv, p);

				bn_mod(rv, rv, n);

				memcpy(m, msg, len);
				bn_write_bin(m + len, FC_BYTES, rv);
				md_map(hash, m, len + FC_BYTES);

				if (8 * MD_LEN > bn_bits(n)) {
					len = CEIL(bn_bits(n), 8);
					bn_read_bin(ev, hash, len);
					bn_rsh(ev, ev, 8 * MD_LEN - bn_bits(n));
				} else {
					bn_read_bin(ev, hash, MD_LEN);
				}

				bn_mod(ev, ev, n);

				result = dv_cmp_const(ev->dp, e->dp, MIN(ev->used, e->used));
				result = (result == CMP_NE ? 0 : 1);

				if (ev->used != e->used) {
					result = 0;
				}
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
		bn_free(ev);
		bn_free(rv);
		ec_free(p);
	}
	return result;
}
示例#13
0
void cp_ecss_sig(bn_t e, bn_t s, unsigned char *msg, int len, bn_t d) {
	bn_t n, k, x, r;
	ec_t p;
	unsigned char hash[MD_LEN];
	unsigned char m[len + EC_BYTES];

	bn_null(n);
	bn_null(k);
	bn_null(x);
	bn_null(r);
	ec_null(p);

	TRY {
		bn_new(n);
		bn_new(k);
		bn_new(x);
		bn_new(r);
		ec_new(p);

		ec_curve_get_ord(n);
		do {
			do {
				bn_rand(k, BN_POS, bn_bits(n));
				bn_mod(k, k, n);
			} while (bn_is_zero(k));

			ec_mul_gen(p, k);
			ec_get_x(x, p);
			bn_mod(r, x, n);
		} while (bn_is_zero(r));

		memcpy(m, msg, len);
		bn_write_bin(m + len, EC_BYTES, r);
		md_map(hash, m, len + EC_BYTES);

		if (8 * MD_LEN > bn_bits(n)) {
			len = CEIL(bn_bits(n), 8);
			bn_read_bin(e, hash, len);
			bn_rsh(e, e, 8 * MD_LEN - bn_bits(n));
		} else {
			bn_read_bin(e, hash, MD_LEN);
		}

		bn_mod(e, e, n);

		bn_mul(s, d, e);
		bn_mod(s, s, n);
		bn_sub(s, n, s);
		bn_add(s, s, k);
		bn_mod(s, s, n);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
		bn_free(k);
		bn_free(x);
		bn_free(r);
		ec_free(p);
	}
}