示例#1
0
END_TEST

/*******************************************************************************
 * test for chunk_hash_static[_inc]()
 */

START_TEST(test_chunk_hash_static)
{
	chunk_t in;
	u_int32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
	int i, count;

	count = countof(sip_vectors);
	in = chunk_alloca(count);

	for (i = 0; i < count; ++i)
	{
		in.ptr[i] = i;
		in.len = i;
		/* compared to chunk_mac() we only get half the value back */
		out = chunk_hash_static(in);
		fail_unless(sipeq(&out, sip_vectors[i], 4),
					"test vector failed for %d bytes", i);
	}
	hash_a = chunk_hash_static_inc(in, out);
	ck_assert_int_eq(hash_a, hash_inc);
	hash_b = chunk_hash_static_inc(in, out);
	ck_assert_int_eq(hash_a, hash_b);
}
示例#2
0
END_TEST

/*******************************************************************************
 * htoun/untoh
 */

START_TEST(test_htoun)
{
	chunk_t net64, expected;
	uint16_t host16 = 513;
	uint32_t net16 = 0, host32 = 67305985;
	uint64_t net32 = 0, host64 = 578437695752307201ULL;

	net64 = chunk_alloca(16);
	memset(net64.ptr, 0, net64.len);

	expected = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
	htoun16((char*)&net16 + 1, host16);
	ck_assert(chunk_equals(expected, chunk_from_thing(net16)));

	expected = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
	htoun32((uint16_t*)&net32 + 1, host32);
	ck_assert(chunk_equals(expected, chunk_from_thing(net32)));

	expected = chunk_from_chars(0x00, 0x00, 0x00, 0x00,
								0x08, 0x07, 0x06, 0x05,
								0x04, 0x03, 0x02, 0x01,
								0x00, 0x00, 0x00, 0x00);
	htoun64((uint32_t*)net64.ptr + 1, host64);
	ck_assert(chunk_equals(expected, net64));
}
示例#3
0
/**
 * Generates a unique fingerprint of the pkcs10 request
 * by computing an MD5 hash over it
 */
chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10)
{
	chunk_t digest = chunk_alloca(HASH_SIZE_MD5);
	hasher_t *hasher;

	hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
	hasher->get_hash(hasher, pkcs10, digest.ptr);
	hasher->destroy(hasher);

	return chunk_to_hex(digest, NULL, FALSE);
}
示例#4
0
/**
 * read the last serial number from file
 */
static chunk_t read_serial(void)
{
	chunk_t hex, serial = chunk_empty;
	char one[] = {0x01};
	FILE *fd;

	fd = fopen(OPENAC_SERIAL, "r");
	if (fd)
	{
		hex = chunk_alloca(64);
		hex.len = fread(hex.ptr, 1, hex.len, fd);
		if (hex.len)
		{
			/* remove any terminating newline character */
			if (hex.ptr[hex.len-1] == '\n')
			{
				hex.len--;
			}
			serial = chunk_alloca((hex.len / 2) + (hex.len % 2));
			serial = chunk_from_hex(hex, serial.ptr);
		}
		fclose(fd);
	}
	else
	{
		DBG1(DBG_LIB, "  file '%s' does not exist yet - serial number "
			 "set to 01", OPENAC_SERIAL);
	}
	if (!serial.len)
	{
		return chunk_clone(chunk_create(one, 1));
	}
	if (chunk_increment(serial))
	{	/* overflow, prepend 0x01 */
		return chunk_cat("cc", chunk_create(one, 1), serial);
	}
	return chunk_clone(serial);
}
示例#5
0
/**
 * Generate a transaction id as the MD5 hash of an public key
 * the transaction id is also used as a unique serial number
 */
void scep_generate_transaction_id(public_key_t *key, chunk_t *transID,
								  chunk_t *serialNumber)
{
	chunk_t digest = chunk_alloca(HASH_SIZE_MD5);
	chunk_t keyEncoding = chunk_empty, keyInfo;
	hasher_t *hasher;
	bool msb_set;
	u_char *pos;

	key->get_encoding(key, PUBKEY_ASN1_DER, &keyEncoding);

	keyInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
						asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
						asn1_bitstring("m", keyEncoding));

	hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
	if (!hasher || !hasher->get_hash(hasher, keyInfo, digest.ptr))
	{
		memset(digest.ptr, 0, digest.len);
	}
	DESTROY_IF(hasher);
	free(keyInfo.ptr);

	/* is the most significant bit of the digest set? */
	msb_set = (*digest.ptr & 0x80) == 0x80;

	/* allocate space for the serialNumber */
	serialNumber->len = msb_set + digest.len;
	serialNumber->ptr = malloc(serialNumber->len);

	/* the serial number as the two's complement of the digest */
	pos = serialNumber->ptr;
	if (msb_set)
	{
		*pos++ = 0x00;
	}
	memcpy(pos, digest.ptr, digest.len);

	/* the transaction id is the serial number in hex format */
	*transID = chunk_to_hex(digest, NULL, TRUE);
}
示例#6
0
static bool do_test_mct(test_vector_t *test)
{
	crypter_t *crypter;
	chunk_t prev, *input, *output;
	int i, j;

	crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC,
										  test->key.len);
	if (!crypter)
	{
		DBG1(DBG_APP, "algorithm %N or key length (%d bits) not supported",
			 encryption_algorithm_names, ENCR_AES_CBC, test->key.len * 8);
		return FALSE;
	}
	input = ctx.decrypt ? &test->cipher : &test->plain;
	output = ctx.decrypt ? &test->plain : &test->cipher;
	if (crypter->get_block_size(crypter) != input->len)
	{
		DBG1(DBG_APP, "MCT only works for input with a length of one block");
		crypter->destroy(crypter);
		return FALSE;
	}
	prev = chunk_alloca(input->len);
	/* assume initial IV as previous output */
	*output = chunk_clone(test->iv);
	for (i = 0; i < 100; i++)
	{
		if (i > 0)
		{	/* we copied the original lines already */
			fprintf(ctx.out, "COUNT = %d\n", i);
			fprintf(ctx.out, "KEY = %+B\n", &test->key);
			fprintf(ctx.out, "IV = %+B\n", &test->iv);
			fprintf(ctx.out, "%s = %+B\n",
					ctx.decrypt ? "CIPHERTEXT" : "PLAINTEXT", input);
		}
		if (!crypter->set_key(crypter, test->key))
		{
			DBG1(DBG_APP, "failed to set key");
			return FALSE;
		}
		for (j = 0; j < 1000; j++)
		{
			/* store previous output as it is used as input after next */
			memcpy(prev.ptr, output->ptr, prev.len);
			chunk_free(output);
			if (!do_crypt(crypter, test))
			{
				crypter->destroy(crypter);
				return FALSE;
			}
			/* prepare the next IV (our API does not allow incremental calls) */
			if (ctx.decrypt)
			{
				memcpy(test->iv.ptr, input->ptr, test->iv.len);
			}
			else
			{
				memcpy(test->iv.ptr, output->ptr, test->iv.len);
			}
			/* the previous output is the next input */
			memcpy(input->ptr, prev.ptr, input->len);
		}
		fprintf(ctx.out, "%s = %+B\n\n",
				ctx.decrypt ? "PLAINTEXT" : "CIPHERTEXT", output);
		/* derive key for next round */
		switch (test->key.len)
		{
			case 16:
				memxor(test->key.ptr, output->ptr, output->len);
				break;
			case 24:
				memxor(test->key.ptr, prev.ptr + 8, 8);
				memxor(test->key.ptr + 8, output->ptr, output->len);
				break;
			case 32:
				memxor(test->key.ptr, prev.ptr, prev.len);
				memxor(test->key.ptr + prev.len, output->ptr, output->len);
				break;
		}
		/* the current output is used as IV for the next round */
		memcpy(test->iv.ptr, output->ptr, test->iv.len);
	}
	crypter->destroy(crypter);
	/* we return FALSE as we print the output ourselves */
	return FALSE;
}
示例#7
0
static bool do_test_gcm(test_vector_t *test)
{
	encryption_algorithm_t alg;
	chunk_t key, iv;
	aead_t *aead;
	size_t saltlen, ivlen;

	switch (ctx.icvlen / 8)
	{
		case 8:
			alg = ENCR_AES_GCM_ICV8;
			break;
		case 12:
			alg = ENCR_AES_GCM_ICV12;
			break;
		case 16:
			alg = ENCR_AES_GCM_ICV16;
			break;
		default:
			DBG1(DBG_APP, "unsupported ICV length: %d", ctx.icvlen);
			return FALSE;
	}

	aead = lib->crypto->create_aead(lib->crypto, alg, test->key.len, 4);
	if (!aead)
	{
		DBG1(DBG_APP, "algorithm %N or key length (%d bits) not supported",
			 encryption_algorithm_names, alg, test->key.len * 8);
		return FALSE;
	}
	/* our API is quite RFC 4106 specific, that is, part of the IV is provided
	 * at the end of the key. */
	saltlen = aead->get_key_size(aead) - test->key.len;
	ivlen = aead->get_iv_size(aead);
	if (ctx.ivlen / 8 != saltlen + ivlen)
	{
		DBG1(DBG_APP, "unsupported IV length: %d", ctx.ivlen);
		aead->destroy(aead);
		return FALSE;
	}
	if (!test->external_iv)
	{
		rng_t *rng;

		/* the IV consists of saltlen random bytes (usually additional keymat)
		 * followed by a counter, zero here */
		test->iv = chunk_alloc(saltlen + ivlen);
		memset(test->iv.ptr, 0, test->iv.len);
		rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
		if (!rng || !rng->get_bytes(rng, saltlen, test->iv.ptr))
		{
			DBG1(DBG_APP, "failed to generate IV");
			DESTROY_IF(rng);
			aead->destroy(aead);
			return FALSE;
		}
		rng->destroy(rng);
	}
	key = chunk_alloca(test->key.len + saltlen);
	memcpy(key.ptr, test->key.ptr, test->key.len);
	memcpy(key.ptr + test->key.len, test->iv.ptr, saltlen);
	iv = chunk_alloca(ivlen);
	memcpy(iv.ptr, test->iv.ptr + saltlen, iv.len);
	if (!aead->set_key(aead, key))
	{
		DBG1(DBG_APP, "failed to set key");
		aead->destroy(aead);
		return FALSE;
	}
	if (ctx.decrypt)
	{
		/* the ICV is expected to follow the cipher text */
		chunk_t cipher = chunk_cata("cc", test->cipher, test->icv);
		/* store if the verification of the ICV verification is successful */
		test->success = aead->decrypt(aead, cipher, test->aad, iv,
									  &test->plain);
	}
	else
	{
		if (!aead->encrypt(aead, test->plain, test->aad, iv, &test->cipher))
		{
			DBG1(DBG_APP, "encryption failed");
			aead->destroy(aead);
			return FALSE;
		}
		/* copy ICV from the end of the cipher text */
		test->icv = chunk_alloc(ctx.icvlen / 8);
		test->cipher.len -= test->icv.len;
		memcpy(test->icv.ptr, test->cipher.ptr + test->cipher.len,
			   test->icv.len);
	}
	aead->destroy(aead);
	return TRUE;
}