Esempio n. 1
0
static bool test_ctr_op(const struct encrypt_desc *encrypt_desc,
			const char *description, int encrypt,
			PK11SymKey *sym_key,
			const char *encoded_cb, const char *output_cb,
			const char *input_name, const char *input,
			const char *output_name, const char *output)
{
	const char *op = encrypt ? "encrypt" : "decrypt";

	bool ok = TRUE;
	chunk_t cb = decode_to_chunk("input counter-block: ", encoded_cb);
	chunk_t tmp = decode_to_chunk(input_name, input);
	chunk_t expected_output = decode_to_chunk(output_name, output);
	chunk_t expected_cb = decode_to_chunk("expected counter-block: ", output_cb);

	/* do_crypt modifies the data and IV in place.  */
	encrypt_desc->encrypt_ops->do_crypt(encrypt_desc, tmp.ptr, tmp.len,
					    sym_key, cb.ptr, encrypt);
	if (!verify_chunk(op, expected_output, tmp)) {
		DBG(DBG_CRYPT, DBG_log("test_ctr_op: %s: %s: output does not match", description, op));
		ok = FALSE;
	}
	if (!verify_chunk("counter-block", expected_cb, cb)) {
		DBG(DBG_CRYPT, DBG_log("test_ctr_op: %s: %s: counter-block does not match", description, op));
		ok = FALSE;
	}

	freeanychunk(cb);
	freeanychunk(expected_cb);
	freeanychunk(tmp);
	freeanychunk(expected_output);

	return ok;
}
Esempio n. 2
0
/*
 * Turn the raw key into a SECItem and then SymKey.
 *
 * Since slots are referenced counted and ImportSymKey adds a
 * reference, immediate freeing of the local slot is possible.
 *
 * ImportSymKey makes a copy of the key chunk so that can also be
 * released.
 */
PK11SymKey *decode_to_key(CK_MECHANISM_TYPE cipher_mechanism,
			  const char *encoded_key)
{
	chunk_t raw_key = decode_to_chunk("key", encoded_key);
	PK11SymKey *sym_key = chunk_to_symkey(cipher_mechanism, raw_key);
	freeanychunk(raw_key);
	return sym_key;
}
Esempio n. 3
0
/*
 * Turn the raw key into SymKey.
 */
PK11SymKey *decode_to_key(const struct encrypt_desc *encrypt_desc,
			  const char *encoded_key)
{
	chunk_t raw_key = decode_to_chunk("raw_key", encoded_key);
	PK11SymKey *symkey = symkey_from_chunk("symkey", DBG_CRYPT,
					       &encrypt_desc->common,
					       raw_key);
	freeanychunk(raw_key);
	return symkey;
}
Esempio n. 4
0
static bool test_gcm_vector(const struct encrypt_desc *encrypt_desc,
			    const struct gcm_test_vector *test)
{
	DBG(DBG_CRYPT, DBG_log("test_gcm_vector: enter"));

	const size_t salt_size = encrypt_desc->salt_size;

	bool ok = TRUE;

	PK11SymKey *sym_key = decode_to_key(encrypt_desc, test->key);

	chunk_t salted_iv = decode_to_chunk("salted IV", test->salted_iv);
	passert(salted_iv.len == encrypt_desc->wire_iv_size + salt_size);
	chunk_t salt = { .ptr = salted_iv.ptr, .len = salt_size };
	chunk_t wire_iv = { .ptr = salted_iv.ptr + salt_size, .len = salted_iv.len - salt_size };

	chunk_t aad = decode_to_chunk("AAD", test->aad);
	chunk_t plaintext = decode_to_chunk("plaintext", test->plaintext);
	chunk_t ciphertext = decode_to_chunk("ciphertext", test->ciphertext);
	passert(plaintext.len == ciphertext.len);
	size_t len = plaintext.len;
	chunk_t tag = decode_to_chunk("tag", test->tag);

	chunk_t text_and_tag;
	text_and_tag.len = len + tag.len;
	text_and_tag.ptr = alloc_bytes(text_and_tag.len, "GCM data");

	/* macro to test encryption or decryption
	 *
	 * This would be better as a function but it uses too many locals
	 * from test_gcm_vector to be pleasant:
	 *	text_and_tag, len, tag, aad, salt, wire_iv, sym_key
	 */
#	define try(enc, desc, from, to) {  \
		memcpy(text_and_tag.ptr, from.ptr, from.len);  \
		text_and_tag.len = len + tag.len;  \
		DBG(DBG_CRYPT,  \
		    DBG_log("test_gcm_vector: %s: aad-size=%zd salt-size=%zd wire-IV-size=%zd text-size=%zd tag-size=%zd",  \
			    desc, aad.len, salt.len, wire_iv.len, len, tag.len);  \
		    DBG_dump_chunk("test_gcm_vector: text+tag on call",  \
				   text_and_tag));  \
		if (!encrypt_desc->encrypt_ops->do_aead(encrypt_desc,  \
							salt.ptr, salt.len, \
							wire_iv.ptr, wire_iv.len, \
							aad.ptr, aad.len, \
							text_and_tag.ptr, \
							len, tag.len,	\
							sym_key, enc) || \
		    !verify_chunk_data("output ciphertext",  \
				   to, text_and_tag.ptr) ||  \
		    !verify_chunk_data("TAG", tag, text_and_tag.ptr + len))  \
			ok = FALSE;  \
		DBG(DBG_CRYPT, DBG_dump_chunk("test_gcm_vector: text+tag on return",  \
					      text_and_tag));  \
	}

	/* test decryption */
	memcpy(text_and_tag.ptr + len, tag.ptr, tag.len);
	try(FALSE, "decrypt", ciphertext, plaintext);

	/* test encryption */
	memset(text_and_tag.ptr + len, '\0', tag.len);
	try(TRUE, "encrypt", plaintext, ciphertext);

#	undef try

	freeanychunk(salted_iv);
	freeanychunk(aad);
	freeanychunk(plaintext);
	freeanychunk(ciphertext);
	freeanychunk(tag);
	freeanychunk(text_and_tag);

	/* Clean up.  */
	release_symkey(__func__, "sym_key", &sym_key);

	DBG(DBG_CRYPT, DBG_log("test_gcm_vector: %s", ok ? "passed" : "failed"));
	return ok;
}

bool test_gcm_vectors(const struct encrypt_desc *encrypt_desc,
		      const struct gcm_test_vector *tests)
{
	bool ok = TRUE;
	const struct gcm_test_vector *test;
	for (test = tests; test->key != NULL; test++) {
		if (!test_gcm_vector(encrypt_desc, test)) {
			ok = FALSE;
		}
	}
	return ok;
}