3

そのため、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 バイトの whirlpool の hmac に 128 バイトの cbc 暗号化時間を追加すると、GCM の約半分の時間である 6795 μs が得られます。

これで、galios フィールドなどのために GHASH は HMAC よりも少し時間がかかることを理解できましたが、私が知っている最も遅い HASH アルゴリズムと比較して 2 倍遅いことは正気ではありません。

それで、私が何か間違ったことをしたのか、それとも CycloneSLL gcm 実装が本当に表示されているのか疑問に思い始めました。残念ながら、C での他の使いやすい GCM 実装を見つけて比較することはできませんでした。

私が使用したすべてのコードは 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 );
4

1 に答える 1

0

あなたの数字は奇妙に思えます.aes-byte-29-08-08の128バイトは、暗号化に64バイトよりも時間がかかりませんか?

RX63N が Cortex-M と同等であると仮定します (どちらも 32 ビットで、ベクトル ユニットがなく、RX63N に関する情報を見つけるのは困難です)。

主張されているSharkSSLのベンチマークでは、CBC は GCM の 2 倍以上の速さであり、速度が最適化されている場合は 2.6 です。9340 は 340 よりもはるかに大きいです。

Cifraのベンチマークでは、AES と AES-GCM の 10 倍の差が示されていますが、GCM テストには認証データも含まれていました。ストレート 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 にあるマイクロコントローラーには適用できないと思います。

※サルサ20はチャチャ20の前身

于 2015-03-27T06:38:45.117 に答える