0

Brian Gladman 博士の AES-CTR 実装を理解しようとしています。(http://gladman.plushost.co.uk/oldsite/AES/aes-src-12-09-11.zip aes_modes.c 849 行目以降) CTR アルゴリズムについて調べましたが、この実装には戸惑いました。CTR モードのアルゴリズムとどのように一致するかわかりません。

if(b_pos) コード セクションとは何ですか?

また、条件 b_pos < AES_BLOCK_SIZE && len がわかりません

(AES_BLOCK_SIZE && len) は、len > 0 の間は常に 1 であるため、AES_BLOCK_SIZE は 16 です。

    if(b_pos)
    {
        memcpy(buf, cbuf, AES_BLOCK_SIZE);
        if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
            return EXIT_FAILURE;

        while(b_pos < AES_BLOCK_SIZE && len)
        {
            *obuf++ = *ibuf++ ^ buf[b_pos++];
            --len;
        }

        if(len)
            ctr_inc(cbuf), b_pos = 0;
    }





AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1])
{   unsigned char   *ip;
    int             i, blen, b_pos = (int)(ctx->inf.b[2]);
    uint_8t buf[BFR_LENGTH];
    if(b_pos)
    {
        memcpy(buf, cbuf, AES_BLOCK_SIZE);
        if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
            return EXIT_FAILURE;

        while(b_pos < AES_BLOCK_SIZE && len)
        {
            *obuf++ = *ibuf++ ^ buf[b_pos++];
            --len;
        }

        if(len)
            ctr_inc(cbuf), b_pos = 0;
    }
    while(len)
    {
        blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;

        for(i = 0, ip = buf; i < (blen >> 4); ++i)
        {
            memcpy(ip, cbuf, AES_BLOCK_SIZE);
            ctr_inc(cbuf);
            ip += AES_BLOCK_SIZE;
        }

        if(blen & (AES_BLOCK_SIZE - 1))
            memcpy(ip, cbuf, AES_BLOCK_SIZE), i++;

        if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
            return EXIT_FAILURE;

        i = 0; ip = buf;
            while(i + AES_BLOCK_SIZE <= blen)
            {
                obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1];
                obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3];
                obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5];
                obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7];
                obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9];
                obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11];
                obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13];
                obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15];
                i += AES_BLOCK_SIZE;
                ip += AES_BLOCK_SIZE;
                ibuf += AES_BLOCK_SIZE;
                obuf += AES_BLOCK_SIZE;
            }

        while(i++ < blen)
            *obuf++ = *ibuf++ ^ ip[b_pos++];
    }
    ctx->inf.b[2] = (uint_8t)b_pos;
    return EXIT_SUCCESS;
}
4

1 に答える 1

1

CTR モードでは、AES がストリーム暗号のように機能します。暗号化および復号化する場合、特にブロック アラインメントに関して (CBC などの他のモードで発生するように)、データ長に制約はありません。

この関数は実際、任意の長さのaes_ctr_crypt()入力データ ( ) で呼び出すことができます。ibuf

問題は、呼び出しごとに、関数が前回の 2 つのことを記憶する必要があることです。

  1. 現在のカウンター ブロックの値(パラメーターcbuf)
  2. 現在のカウンタ ブロックでこれまでに消費したバイト数(パラメータに保持ctxされ、ローカル変数にコピーされた情報b_pos)。

b_posしたがって、16 を法とするキー ストリーム内の位置です。

つまり、関数が最後のカウンター ブロックの 16 バイトすべてを消費することなく特定のデータの暗号化を完了すると、次の呼び出しで関数がそこから続行できるようにb_pos、値が残されます。0<b_pos<16の値は、前のカウンタ ブロック0のすべてのバイトが使い果たされ、カウンタ関数を呼び出すときが来たことを意味します。

についてb_pos < AES_BLOCK_SIZE && lenは、次のように読む必要があります。

(b_pos < AES_BLOCK_SIZE) && len

演算子の優先順位のため。ループは、「残りの」キー ストリーム バイトがなくなるか (左側)、クリアテキスト データがなくなるか (右側) のいずれかで終了します。

于 2012-09-13T20:22:12.603 に答える