1

Linux に組み込まれている暗号化 API をさまざまな目的で使用するので、ソースを注意深く読んでいます。
何が起こっているのかを理解しようとしているときに、コードのインスタンス処理部分に感銘を受けました。

コードは C ですが、この部分は明らかにオブジェクト指向です。したがって、ユーザーが何らかの暗号化を実行する必要がある場合、特定の暗号化モードで特定のアルゴリズムを使用する変換インスタンスの割り当てを要求します。ペア (アルゴリズムモード) は、暗号 API で次のように処理されます。

  1. 「純粋な」アルゴリズムはstruct crypto_alg構造体に格納されます。
  2. モードはstruct crypto_template、特定のstruct crypto_instance

ここに構造の定義crypto_instancecrypto_spawn

struct crypto_instance {
    struct crypto_alg alg;
    /*
     * The alg struct will be filled according to the template 'alloc' method
     */
    struct crypto_template *tmpl;
    struct hlist_node list;

    void *__ctx[] CRYPTO_MINALIGN_ATTR;
};

struct crypto_spawn {
    struct list_head list; // Embedded list_head to list the spawns
    struct crypto_alg *alg; // Ptr to the underlying algorithm
    struct crypto_instance *inst;
    const struct crypto_type *frontend;
    u32 mask;
}

次に、一種の階層があるように見えます。 は、crypto_spawnによって定義された暗号化モードと によって定義されcrypto_instance純粋な暗号化アルゴリズムの組み合わせを管理するためにここにありcrypto_algます。crypto_instanceモデル オブジェクトに関しては、それが継承されていることがわかりcrypto_algます。特定のアルゴリズムでテンプレートを「カスケード」することを検討することは完全に合理的です。

crypto_spawn理解できないのは、と のcrypto_instance構造が結合されていない理由です。インスタンス割り当てコードに出会ったとき、この質問はさらに私を襲った:

struct crypto_instance *crypto_alloc_instance(const char *name,
                                struct crypto_alg *alg)
{
    struct crypto_instance *inst;
    struct crypto_spawn *spawn;
    int err;

    inst = crypto_alloc_instance2(name, alg, 0);
    if (IS_ERR(inst))
        goto out;

    spawn = crypto_instance_ctx(inst);
    /*
     * This line expands to :
     * spawn = inst->__ctx;
     */
    err = crypto_init_spawn(spawn, alg, inst,
                CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);

    if (err)
        goto err_free_inst;

    return inst;

err_free_inst:
    kfree(inst);
    inst = ERR_PTR(err);

out:
    return inst;
}

crypto_alloc_instance2構造体を保持するために物理メモリを割り当て、構造体の名前フィールドを埋めるだけinst->algです。

void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
                        unsigned int head)
{
    struct crypto_instance *inst;
    char *p;
    int err;

    p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
                GFP_KERNEL);
    if (!p)
        return ERR_PTR(-ENOMEM);

    inst = (void *)(p + head);
    /* Names editing + error checking ... */
    return p;
}

ご覧のとおり、スポーンは「物理的に」インスタンスにバインドされているため、なぜ別々に定義されているのでしょうか。全体がどのように混合され、処理されるかを理解しようとすると、非常に厄介です。

現時点で、私の頭に浮かんだ唯一の理由は、API がオブジェクトから基礎となるアルゴリズムを不透明crypto_instance化できるようにすることです。しかし、構造体の最後のバイトはspawn = inst->__ctx命令を介して簡単にスポーンを与えるため、それほど不透明ではありません。

この一連のコードとコメントの後の思い出として、質問は次のとおりです。 開発者がインスタンスとスポーン構造の間にこの「分離」を行う理由は何ですか?

啓蒙をよろしくお願いします!

: タグ cryptography を追加したのは、このタグに関心のある開発者はおそらく Linux カーネルの暗号化部分を既に調べていると考えたからです。

4

0 に答える 0