END_TEST /******************************************************************************* * chunk_create_cat */ START_TEST(test_chunk_create_cat) { chunk_t foo, bar; chunk_t a, b, c; u_char *ptra, *ptrb; foo = chunk_from_str("foo"); bar = chunk_from_str("bar"); /* to simplify things we use the chunk_cata macro */ a = chunk_empty; b = chunk_empty; c = chunk_cata("cc", a, b); ck_assert_int_eq(c.len, 0); ck_assert(c.ptr != NULL); a = foo; b = bar; c = chunk_cata("cc", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); a = chunk_clone(foo); b = chunk_clone(bar); c = chunk_cata("mm", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); a = chunk_clone(foo); b = chunk_clone(bar); ptra = a.ptr; ptrb = b.ptr; c = chunk_cata("ss", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); /* check memory area of cleared chunk */ ck_assert(!chunk_equals(foo, chunk_create(ptra, 3))); ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3))); }
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; }