Linux に組み込まれている暗号化 API をさまざまな目的で使用するので、ソースを注意深く読んでいます。
何が起こっているのかを理解しようとしているときに、コードのインスタンス処理部分に感銘を受けました。
コードは C ですが、この部分は明らかにオブジェクト指向です。したがって、ユーザーが何らかの暗号化を実行する必要がある場合、特定の暗号化モードで特定のアルゴリズムを使用する変換インスタンスの割り当てを要求します。ペア (アルゴリズム、モード) は、暗号 API で次のように処理されます。
- 「純粋な」アルゴリズムは
struct crypto_alg
構造体に格納されます。 - モードは
struct crypto_template
、特定のstruct crypto_instance
ここに構造の定義crypto_instance
とcrypto_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 カーネルの暗号化部分を既に調べていると考えたからです。