Developing Cipher Algorithms(2/2)

https://www.kernel.org/doc/html/latest/crypto/devel-algos.html


Docs » Linux Kernel Crypto API » Developing Cipher Algorithms

# Hashing [HASH]
Example of transformations: crc32, md5, sha1, sha256,…

## Registering And Unregistering The Transformation

> There are multiple ways to register a HASH transformation, depending on whether the transformation is synchronous [SHASH] or asynchronous [AHASH] and the amount of HASH transformations we are registering. You can find the prototypes defined in include/crypto/internal/hash.h:

HASH transformationを登録するための複数の方法があります。変換が同期的(synchronous)か[SHASH]、非同期的(asynchromous) [AHASH]、そして登録しようとするHASH transformations の数に応じて変わります。プロとライプは、include/crypto/internal/hash.hで見つけることができます。

```c:
int crypto_register_ahash(struct ahash_alg *alg);

int crypto_register_shash(struct shash_alg *alg);
int crypto_register_shashes(struct shash_alg *algs, int count);
```

> The respective counterparts for unregistering the HASH transformation are as follows:

HASH transformationを登録解除するためのそれぞれの方法は以下となります。

```c
void crypto_unregister_ahash(struct ahash_alg *alg);

void crypto_unregister_shash(struct shash_alg *alg);
void crypto_unregister_shashes(struct shash_alg *algs, int count);
```

## Cipher Definition With struct shash_alg and ahash_alg

> Here are schematics of how these functions are called when operated from other part of the kernel. Note that the .setkey() call might happen before or after any of these schematics happen, but must not happen during any of these are in-flight. Please note that calling .init() followed immediately by .finish() is also a perfectly valid transformation.

以下に、カーネルの他の部分から処理を呼び出されたときに、これらの関数がどのように呼び出されるのかの図です。.setkry()の呼び出しは、これらの図の発生する前、あるいは発生した後に発生することに気を付けてください。しかし、処理実行中には呼び出されません。.init()が突然呼ばれた直後に.finish()を呼び出す事も、有効な変換であることに注意してください。

```plaintext

I)   DATA -----------.
                     v
      .init() -> .update() -> .final()      ! .update() might not be called
                  ^    |         |            at all in this scenario.
                  '----'         '---> HASH

II)  DATA -----------.-----------.
                     v           v
      .init() -> .update() -> .finup()      ! .update() may not be called
                  ^    |         |            at all in this scenario.
                  '----'         '---> HASH

III) DATA -----------.
                     v
                 .digest()                  ! The entire process is handled
                     |                        by the .digest() call.
                     '---------------> HASH
```

> Here is a schematic of how the .export()/.import() functions are called when used from another part of the kernel.

ここで、カーネルの他の部分つかう時に.export()/.import()関数がそのように呼ばれるのかを示します。

```plaintext

KEY--.                 DATA--.
     v                       v                  ! .update() may not be called
 .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
                          ^     |         |
                          '-----'         '--> PARTIAL_HASH

----------- other transformations happen here -----------

PARTIAL_HASH--.   DATA1--.
              v          v
          .import -> .update() -> .final()     ! .update() may not be called
                      ^    |         |           at all in this scenario.
                      '----'         '--> HASH1

PARTIAL_HASH--.   DATA2-.
              v         v
          .import -> .finup()
                        |
                        '---------------> HASH2
```

> Note that it is perfectly legal to “abandon” a request object: - call .init() and then (as many times) .update() - _not_ call any of .final(), .finup() or .export() at any point in future

要求するオブジェクトを"破棄"することが、完全に想定していることであることに注意してください。 init()を呼び出し（そして複数回) .update()を、最後に将来いつでも.final()やexport()は呼び出したり呼び出さなかったりします。

> In other words implementations should mind the resource allocation and clean-up. No resources related to request objects should remain allocated after a call to .init() or .update(), since there might be no chance to free them.

言い換えると、実装ではresource allocation と clean-upについて注意をしなければなりません。request objectと関係がないリソースは、.init()や.update()を呼び出した後に残りを確保しなければならなく、それらは解放されるチャンスがありません。

## Specifics Of Asynchronous HASH Transformation

> Some of the drivers will want to use the Generic ScatterWalk in case the implementation needs to be fed separate chunks of the scatterlist which contains the input data. The buffer containing the resulting hash will always be properly aligned to .cra_alignmask so there is no need to worry about this.

ドライバーの中には、入力データに含まれているscatterlistの分割されたchunksを処理するため実装が必要となるケースでは、Generic ScatterWalkを使おうとするものもあります。結果のhashを含むバッファーは、常に、.cra_alignmaskに適切に配置されるため、これを考慮する必要はありません。

---

もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（はずの認識）。

> https://www.kernel.org/doc/html/latest/index.html
> 
> Licensing documentation
> 
> The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
> 
> https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing