/* Data format is iv | enc(4 byte len | ptxt | 0 padding) | tag
*/
- int dipe_aes_encrypt(uint8_t* key, size_t ptxt_len, uint8_t* ptxt, size_t ctxt_len, uint8_t* ctxt) {
+ int dipe_aes_encrypt(uint8_t* key, uint8_t* iv, size_t ptxt_len, uint8_t* ptxt, size_t ctxt_len, uint8_t* ctxt) {
struct gcm_aes128_ctx ctx;
- uint8_t iv[12];
uint8_t block[16];
uint32_t coded_ptxtlen;
- ctxt_len -= (12 + 16); /* IV + Tag */
- if (ctxt_len < ptxt_len) return -1;
+ ctxt_len -= 16; /* Tag */
+ if (ctxt_len < ptxt_len + 4) return 0;
- getrandom(iv, 12, 0);
- memcpy(ctxt, iv, 12);
- ctxt += 12;
memset(block, 0, 16);
gcm_aes128_set_key(&ctx, key);
gcm_aes128_set_iv(&ctx, 12, iv);
return 0;
}
- int dipe_aes_decrypt(uint8_t* key, size_t len, uint8_t* ctxt, uint8_t* ptxt) {
+ int dipe_aes_decrypt(uint8_t* key, uint8_t* iv, size_t len, uint8_t* ctxt, uint8_t* ptxt) {
struct gcm_aes128_ctx ctx;
uint8_t block[16];
gcm_aes128_set_key(&ctx, key);
- gcm_aes128_set_iv(&ctx, 12, ctxt);
- ctxt += 12; len -= 12;
+ gcm_aes128_set_iv(&ctx, 12, iv);
len -= 16; /* GCM tag */
cap_len = dipe_serialize_ctxt(param, cap, (uint8_t*)ctxt);
ctxt += cap_len; ctxt_len -= cap_len;
- dipe_aes_encrypt(aes, ptxt_len, (uint8_t*)ptxt, ctxt_len, (uint8_t*)ctxt);
+ dipe_aes_encrypt(aes, aes+16, ptxt_len, (uint8_t*)ptxt, ctxt_len, (uint8_t*)ctxt);
dipe_free_ctxt(cap);
element_clear(key);
dipe_free_ctxt(cap);
element_clear(key);
- return dipe_aes_decrypt(aes, ctxt_len, (uint8_t*)ctxt, (uint8_t*)ptxt);
+ return dipe_aes_decrypt(aes, aes+16, ctxt_len, (uint8_t*)ctxt, (uint8_t*)ptxt);
}
/* Note: we're generating random-looking bytes here. Therefore we
}
size_t dipe_ciphertext_overhead(dipe_param_t param, size_t dimension) {
- size_t overhead = 12 + 16 + 4 /* IV + Tag + Size */;
+ size_t overhead = 16 + 4 /* IV + Tag + Size */;
element_t t;
element_init_G1(t, param->pairing);
}
TEST(DipeTest, DipeDecryptSuccessSmall) {
- char ctxt[768];
- char ptxt[768];
+ char ctxt[672];
+ char ptxt[672];
size_t ptxt_len;
size_t overhead;
dipe_master_publickey_t pk;
dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
overhead = dipe_ciphertext_overhead(param, 6);
- for (size_t clen = overhead; clen < 768; ++clen) {
- memset(ctxt, 0, 768);
- memset(ptxt, 0, 768);
+ for (size_t clen = overhead; clen < 672; ++clen) {
+ memset(ctxt, 0, 672);
+ memset(ptxt, 0, 672);
memcpy(ptxt, "test", 4);
dipe_encrypt(param, pk, x, 4, ptxt, clen, ctxt);
ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
- if (clen >= overhead) {
- ASSERT_EQ(ptxt_len, 4);
- ASSERT_STREQ(ptxt, "test");
+ if (clen >= overhead + 4) {
+ EXPECT_EQ(ptxt_len, 4);
+ EXPECT_STREQ(ptxt, "test");
}
else {
- ASSERT_EQ(ptxt_len, 0);
+ EXPECT_EQ(ptxt_len, 0);
}
}
-
+
+ for (size_t i = 0; i < 6; ++i) {
+ element_clear(y[i]);
+ element_clear(x[i]);
+ }
+
+ dipe_free_master_secretkey(msk);
+ dipe_free_master_publickey(pk);
+ dipe_free_secretkey(sk);
+}
+
+TEST(DipeTest, DipeDecryptSuccessTightSmall) {
+ size_t ptxt_len;
+ size_t overhead;
+ dipe_master_publickey_t pk;
+ dipe_master_secretkey_t msk;
+ dipe_secretkey_t sk;
+
+ element_t y[6];
+ element_t x[6];
+
+ for (size_t i = 0; i < 6; i+=2) {
+ element_init_Zr(y[i], *dipe_get_pairing(param));
+ element_init_Zr(x[i], *dipe_get_pairing(param));
+ element_init_Zr(y[i+1], *dipe_get_pairing(param));
+ element_init_Zr(x[i+1], *dipe_get_pairing(param));
+
+ element_set1(y[i]);
+ element_set1(x[i+1]);
+ element_random(y[i+1]);
+ element_neg(x[i], y[i+1]);
+ }
+
+ dipe_master_keygen(param, 6, &pk, &msk);
+ dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+ overhead = dipe_ciphertext_overhead(param, 6);
+
+ char ctxt[overhead + 4];
+ char ptxt[overhead + 4];
+
+ for (size_t clen = overhead; clen <= overhead + 4; ++clen) {
+ memset(ctxt, 0, overhead + 4);
+ memset(ptxt, 0, overhead + 4);
+ memcpy(ptxt, "test", 4);
+
+ dipe_encrypt(param, pk, x, 4, ptxt, clen, ctxt);
+ ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+
+ if (clen >= overhead + 4) {
+ EXPECT_EQ(ptxt_len, 4);
+ EXPECT_STREQ(ptxt, "test");
+ }
+ else {
+ EXPECT_EQ(ptxt_len, 0);
+ }
+ }
+
+ for (size_t i = 0; i < 6; ++i) {
+ element_clear(y[i]);
+ element_clear(x[i]);
+ }
+
+ dipe_free_master_secretkey(msk);
+ dipe_free_master_publickey(pk);
+ dipe_free_secretkey(sk);
+}
+
+
+TEST(DipeTest, DipeDecryptSuccessLargeBlocksize) {
+ char ctxt[672];
+ char ptxt[672];
+ size_t ptxt_len;
+ size_t overhead;
+ dipe_master_publickey_t pk;
+ dipe_master_secretkey_t msk;
+ dipe_secretkey_t sk;
+
+ element_t y[6];
+ element_t x[6];
+
+ for (size_t i = 0; i < 6; i+=2) {
+ element_init_Zr(y[i], *dipe_get_pairing(param));
+ element_init_Zr(x[i], *dipe_get_pairing(param));
+ element_init_Zr(y[i+1], *dipe_get_pairing(param));
+ element_init_Zr(x[i+1], *dipe_get_pairing(param));
+
+ element_set1(y[i]);
+ element_set1(x[i+1]);
+ element_random(y[i+1]);
+ element_neg(x[i], y[i+1]);
+ }
+
+ dipe_master_keygen(param, 6, &pk, &msk);
+ dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+ overhead = dipe_ciphertext_overhead(param, 6);
+
+ for (size_t clen = overhead; clen <= 672; ++clen) {
+ memset(ctxt, 0, 672);
+ memset(ptxt, 0, 672);
+ memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
+
+ dipe_encrypt(param, pk, x, 28, ptxt, clen, ctxt);
+ ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+
+ if (clen >= overhead + 28) {
+ EXPECT_EQ(ptxt_len, 28);
+ EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb");
+ }
+ else {
+ EXPECT_EQ(ptxt_len, 0);
+ }
+ }
+
for (size_t i = 0; i < 6; ++i) {
element_clear(y[i]);
element_clear(x[i]);
dipe_free_secretkey(sk);
}
+TEST(DipeTest, DipeDecryptSuccessTightLargeBlocksize) {
+ size_t ptxt_len;
+ size_t overhead;
+ dipe_master_publickey_t pk;
+ dipe_master_secretkey_t msk;
+ dipe_secretkey_t sk;
+
+ element_t y[6];
+ element_t x[6];
+
+ for (size_t i = 0; i < 6; i+=2) {
+ element_init_Zr(y[i], *dipe_get_pairing(param));
+ element_init_Zr(x[i], *dipe_get_pairing(param));
+ element_init_Zr(y[i+1], *dipe_get_pairing(param));
+ element_init_Zr(x[i+1], *dipe_get_pairing(param));
+
+ element_set1(y[i]);
+ element_set1(x[i+1]);
+ element_random(y[i+1]);
+ element_neg(x[i], y[i+1]);
+ }
+
+ dipe_master_keygen(param, 6, &pk, &msk);
+ dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+ overhead = dipe_ciphertext_overhead(param, 6);
+
+ char ctxt[overhead + 28];
+ char ptxt[overhead + 28];
+
+
+ for (size_t clen = overhead; clen <= overhead + 28; ++clen) {
+ memset(ctxt, 0, overhead + 28);
+ memset(ptxt, 0, overhead + 28);
+ memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
+
+ dipe_encrypt(param, pk, x, 28, ptxt, clen, ctxt);
+ ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+
+ if (clen >= overhead + 28) {
+ EXPECT_EQ(ptxt_len, 28);
+ EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb");
+ }
+ else {
+ EXPECT_EQ(ptxt_len, 0);
+ }
+ }
+
+ for (size_t i = 0; i < 6; ++i) {
+ element_clear(y[i]);
+ element_clear(x[i]);
+ }
+
+ dipe_free_master_secretkey(msk);
+ dipe_free_master_publickey(pk);
+ dipe_free_secretkey(sk);
+}
+
+
+TEST(DipeTest, DipeDecryptSuccessLargeNonBlocksize) {
+ char ctxt[672];
+ char ptxt[672];
+ size_t ptxt_len;
+ size_t overhead;
+ dipe_master_publickey_t pk;
+ dipe_master_secretkey_t msk;
+ dipe_secretkey_t sk;
+
+ element_t y[6];
+ element_t x[6];
+
+ for (size_t i = 0; i < 6; i+=2) {
+ element_init_Zr(y[i], *dipe_get_pairing(param));
+ element_init_Zr(x[i], *dipe_get_pairing(param));
+ element_init_Zr(y[i+1], *dipe_get_pairing(param));
+ element_init_Zr(x[i+1], *dipe_get_pairing(param));
+
+ element_set1(y[i]);
+ element_set1(x[i+1]);
+ element_random(y[i+1]);
+ element_neg(x[i], y[i+1]);
+ }
+
+ dipe_master_keygen(param, 6, &pk, &msk);
+ dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+ overhead = dipe_ciphertext_overhead(param, 6);
+
+ for (size_t clen = overhead; clen <= 672; ++clen) {
+ memset(ctxt, 0, 672);
+ memset(ptxt, 0, 672);
+ memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
+
+ dipe_encrypt(param, pk, x, 35, ptxt, clen, ctxt);
+ ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+
+ if (clen >= overhead + 35) {
+ EXPECT_EQ(ptxt_len, 35);
+ EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc");
+ }
+ else {
+ EXPECT_EQ(ptxt_len, 0);
+ }
+ }
+
+ for (size_t i = 0; i < 6; ++i) {
+ element_clear(y[i]);
+ element_clear(x[i]);
+ }
+
+ dipe_free_master_secretkey(msk);
+ dipe_free_master_publickey(pk);
+ dipe_free_secretkey(sk);
+}
+
+TEST(DipeTest, DipeDecryptSuccessTightLargeNonBlocksize) {
+ size_t ptxt_len;
+ size_t overhead;
+ dipe_master_publickey_t pk;
+ dipe_master_secretkey_t msk;
+ dipe_secretkey_t sk;
+
+ element_t y[6];
+ element_t x[6];
+
+ for (size_t i = 0; i < 6; i+=2) {
+ element_init_Zr(y[i], *dipe_get_pairing(param));
+ element_init_Zr(x[i], *dipe_get_pairing(param));
+ element_init_Zr(y[i+1], *dipe_get_pairing(param));
+ element_init_Zr(x[i+1], *dipe_get_pairing(param));
+
+ element_set1(y[i]);
+ element_set1(x[i+1]);
+ element_random(y[i+1]);
+ element_neg(x[i], y[i+1]);
+ }
+
+ dipe_master_keygen(param, 6, &pk, &msk);
+ dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+ overhead = dipe_ciphertext_overhead(param, 6);
+
+ char ctxt[overhead + 35];
+ char ptxt[overhead + 35];
+
+
+ for (size_t clen = overhead; clen <= overhead + 35; ++clen) {
+ memset(ctxt, 0, overhead + 35);
+ memset(ptxt, 0, overhead + 35);
+ memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
+
+ dipe_encrypt(param, pk, x, 35, ptxt, clen, ctxt);
+ ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+
+ if (clen >= overhead + 35) {
+ EXPECT_EQ(ptxt_len, 35);
+ EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc");
+ }
+ else {
+ EXPECT_EQ(ptxt_len, 0);
+ }
+ }
+
+ for (size_t i = 0; i < 6; ++i) {
+ element_clear(y[i]);
+ element_clear(x[i]);
+ }
+
+ dipe_free_master_secretkey(msk);
+ dipe_free_master_publickey(pk);
+ dipe_free_secretkey(sk);
+}
+
+
+
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);