gpt4 book ai didi

c - AES-CBC + HMAC 和 AES-GCM 之间的极端时间差异

转载 作者:行者123 更新时间:2023-12-03 12:15:25 28 4
gpt4 key购买 nike

所以我一直在广泛地寻找 CBC 和 GCM 的不同 AES 实现,我不想自己实现这个,以防我出错,所以我找到了以下 AES CBC 代码并在我的 RX63NB 上测试了它们的速度(瑞萨测试板)。

                    Encrypt                 Decrypt 
bytes speed (us) bytes speed (us)
Tiny AES 64 1500 64 8900
128 2880 128 17820
aes-byte-29-08-08 64 1250 64 4900
128 1220 128 9740
Cyclone 64 230 64 237
128 375 128 387

我对 Cyclone 的速度有多快感到惊讶,为了澄清我从 CycloneSSL 获取了 AES、CBC 和 Endian 文件并且只使用了那些。

然后我尝试了 CycloneSSl 的 GCM,这是输出:
                    Encrypt                 Decrypt 
bytes speed μs bytes speed μs
Cyclone GCM 64 9340 64 9340
128 14900 128 14900

我检查了 HMAC 时间(来自 CycloneSSL),看看需要多少时间:
HMAC        bytes   speed μs
Sha1 64 746
128 857
Sha224 64 918
128 1066
Sha256 64 918
128 1066
Sha384 64 2395
128 2840
Sha512 64 2400
128 2840
Sha512_224 64 2390
128 2835
Sha512_356 64 2390
128 2835
MD5 64 308
128 345
Whirlpool 64 5630
128 6420
Tiger 64 832
128 952

其中最慢的是漩涡。

如果您将 128 字节的 cbc 加密时间添加到带有 128 字节的漩涡的 hmac 中,您将获得 6795 μs,这大约是 GCM 所需时间的一半。

现在我可以理解,由于 galios 字段等原因,GHASH 比 HMAC 需要更长的时间,但与我知道的最慢的 HASH 算法相比,它的速度要慢 2 倍,这太疯狂了。

所以我开始怀疑我是否做错了什么,或者 CycloneSLL gcm 的实现是否真的很明显。不幸的是,我还没有在 c 中找到其他易于使用的 GCM 实现来与之进行比较。

我使用的所有代码都可以是 found on pastebin , 不同的文件用 -------------------- 分隔

这是我用来用 GCM 加密的代码:
static void test_encrypt(void)
{
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t in[] = { 0x48, 0x61, 0x6c, 0x6c, 0x6f, 0x20, 0x68, 0x6f, 0x65, 0x20, 0x67, 0x61, 0x61, 0x74, 0x20, 0x68,
0x65, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x6a, 0x6f, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x64, 0x61,
0x61, 0x67, 0x2c, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x6d, 0x69, 0x6a, 0x20, 0x67, 0x61, 0x61, 0x74,
0x20, 0x68, 0x65, 0x74, 0x20, 0x67, 0x6f, 0x65, 0x64, 0x20, 0x68, 0x6f, 0x6f, 0x72, 0x2e, 0x21,
0x48, 0x61, 0x6c, 0x6c, 0x6f, 0x20, 0x68, 0x6f, 0x65, 0x20, 0x67, 0x61, 0x61, 0x74, 0x20, 0x68,
0x65, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x6a, 0x6f, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x64, 0x61,
0x61, 0x67, 0x2c, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x6d, 0x69, 0x6a, 0x20, 0x67, 0x61, 0x61, 0x74,
0x20, 0x68, 0x65, 0x74, 0x20, 0x67, 0x6f, 0x65, 0x64, 0x20, 0x68, 0x6f, 0x6f, 0x72, 0x2e, 0x21};

AesContext context;
aesInit(&context, key, 16 ); // 16 byte = 128 bit
error_crypto_t error = gcmEncrypt(AES_CIPHER_ALGO, &context, iv, 16, 0, 0, in, in, 128, key, 16);
}

static void test_decrypt(void)
{
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t tag[] = { 0x56, 0x56, 0x5C, 0xCD, 0x5C, 0x57, 0x36, 0x66, 0x73, 0xF7, 0xFF, 0x2A, 0x17, 0x49, 0x0E, 0xC4};
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t out[] = { 0x05, 0x7C, 0x51, 0xFF, 0xE4, 0x9F, 0x8C, 0x90, 0xF1, 0x7D, 0x56, 0xFB, 0x87, 0xB9, 0x44, 0x79,
0xB1, 0x04, 0x32, 0x39, 0x78, 0xFF, 0x51, 0x60, 0x48, 0x0B, 0x21, 0x77, 0xF2, 0x26, 0x0B, 0x94,
0x7B, 0xA7, 0x26, 0x74, 0x87, 0xA8, 0x2C, 0x5A, 0xA1, 0x19, 0x03, 0x17, 0x66, 0x3A, 0x46, 0x9F,
0xE6, 0x1D, 0x3B, 0x65, 0xFD, 0xC0, 0xBA, 0xC0, 0xD9, 0x45, 0xE7, 0x17, 0x74, 0x0F, 0xB7, 0x4B,
0x0F, 0xF0, 0x16, 0xF6, 0xE8, 0x4F, 0xFD, 0x96, 0x64, 0x5E, 0xDB, 0x9E, 0x3A, 0x0B, 0x93, 0x8F,
0x87, 0x83, 0x90, 0xF8, 0xF9, 0xE6, 0xA3, 0xE7, 0x5E, 0x72, 0x3C, 0xB5, 0x98, 0x54, 0x11, 0xD7,
0xB4, 0x7C, 0xFF, 0xA3, 0x51, 0x1A, 0xB0, 0x69, 0x4F, 0x57, 0xBB, 0x83, 0x40, 0x2A, 0xE6, 0x75,
0x8B, 0xB5, 0xCA, 0xA4, 0x84, 0x82, 0x1D, 0xA8, 0x94, 0x03, 0x77, 0x9C, 0x3B, 0xF8, 0xA0, 0x60};

AesContext context;
aesInit(&context, key, 16 ); // 16 byte = 128 bit
error_crypto_t error = gcmDecrypt(AES_CIPHER_ALGO, &context, iv, 16, 0, 0, out, out, 128, tag, 16);
}

out[] 中的数据是来自 in[] 的 gcm 加密数据,并且一切正常。 (正确解密并通过身份验证。

问题
  • 所有 GCM 实现都这么慢吗?
  • 还有其他(更好的)GCM 实现吗?
  • 如果我想要快速加密+验证,我应该只使用 HMAC 吗?

  • 编辑

    我已经能够从 mbedTLS (PolarSSL) 获得 GCM 方法工作速度比旋风快 11 倍(加密/解密 128 个字节需要 880us)。它产生与 cylcone GCM 相同的输出,所以我相信它可以正常工作。
    gcm_context gcm_ctx;
    gcm_init(&gcm_ctx, POLARSSL_CIPHER_ID_AES,key, 128);
    int error = gcm_auth_decrypt(&gcm_ctx, 128,iv, 16, NULL, 0, tag, 16, out, buffer );

    最佳答案

    你的数字看起来很奇怪,aes-byte-29-08-08 的 128 字节比 64 字节的加密时间少?

    假设 RX63N 与 Cortex-M 相当(它们都是 32 位的,没有 vector 单元,而且很难找到关于 RX63N 的信息):

    SharkSSL 声称的基准使 CBC 的速度是 GCM 的两倍多,如果针对速度进行了优化,则为 2.6。 9340比340大很多。

    Cifra的基准测试显示他们的 AES 和 AES-GCM 之间存在 10 倍的差异,尽管 GCM 测试还包括 auth-data。仍然远未接近直接 AES 和 GCM 之间的差异。

    所以相对而言,要回答 1,我不认为所有 GCM 实现相对于普通 AES 都那么慢。

    至于其他的 GCM 实现,还有前面提到的 Cifra(虽然我直到现在才听说它,而且它在 GitHub 上只有 3 颗星(如果这意味着什么的话),所以审核级别可能相当低) ,也许您可​​以从 FreeBSD 中删除 AES-GCM 实现.尽管在您的平台上绝对不能谈论性能。

    不管实现如何,HMAC 在没有硬件支持(如 AES-NI 支持(CLMUL))的平台上可能会更快。这对性能有多重要?您必须使用 AES 还是分组密码?也许 ChaCha20+Poly1305 更适合您的性能需求(请参阅 Cifra 的性能数据)。现在在 OpenSSH 中使用- chacha.* 和 poly1305.*

    注意旁道攻击。 AES 的软件实现可能对缓存定时攻击很敏感,尽管我认为这不适用于所有东西都在 SRAM 中的微 Controller 。

    *Salsa20 是 ChaCha20 的前身

    关于c - AES-CBC + HMAC 和 AES-GCM 之间的极端时间差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29142980/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com