1# MD Operation (C/C++)
2
3
4The message digest (MD) algorithm allows a fixed-length digest to be generated from data of arbitrary size by using the hash algorithm. The MD algorithm is also referred to as a hash algorithm or a one-way hash algorithm.
5
6
7When the same digest algorithm is used, the generated digest (hash value) has the following features:
8
9
10- The same message always results in the same hash value.
11
12- The digest generated is of the fixed length no matter the length of messages. (The digest length is determined by the algorithm used).
13
14- It is almost impossible to find two different messages with the same hash value. (The probability still exists, depending on the length of the digest.)
15
16
17## Supported Algorithms and Specifications
18
19The **Supported Type** column in the following table lists the algorithm to be used when a **Md** instance is created.
20
21| MD Algorithm| Supported Type| API Version| 
22| -------- | -------- | -------- |
23| HASH | SHA1 | 9+ | 
24| HASH | SHA224 | 9+ | 
25| HASH | SHA256 | 9+ | 
26| HASH | SHA384 | 9+ | 
27| HASH | SHA512 | 9+ | 
28| HASH | MD5 | 9+ | 
29| HASH | SM3 | 10+ | 
30
31
32## Adding the Dynamic Library in the CMake Script
33```txt
34   target_link_libraries(entry PUBLIC libohcrypto.so)
35```
36
37
38## How to Develop
39
40During the MD operation, you can use **OH_CryptoDigest_Update()** to pass in all the data at a time or pass in data by segment. For the same piece of data, the result will be the same no matter how the data is passed. Use the appropriate method based on the data size.
41
42The following provides examples of MD operations with different data passing methods.
43
44
45### MD (Passing In Full Data)
46
471. Use [OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create) with the MD algorithm **SHA256** to generate an MD operation instance ([OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest)).
48
492. Use [OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update) to pass in the data for generating an MD. The amount of data to be passed in by a single **OH_CryptoDigest_Update()** operation is not limited.
50
513. Use [OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final) to generate an MD.
52
534. Use [OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength) to obtain the MD length, in bytes.
54
555. Use [OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy) to destroy the [OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest) instance.
56
57**Example**
58
59```c++
60#include "CryptoArchitectureKit/crypto_common.h"
61#include "CryptoArchitectureKit/crypto_digest.h"
62
63static OH_Crypto_ErrCode doTestMd()
64{
65    OH_Crypto_ErrCode ret;
66    OH_CryptoDigest *ctx = nullptr;
67    uint8_t testData[] = "0123456789";
68    Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData), .len = sizeof(testData)};
69    Crypto_DataBlob out = {.data = nullptr, .len = 0};
70    int mdLen = 0;
71    ret = OH_CryptoDigest_Create("SHA256", &ctx);
72    if (ret != CRYPTO_SUCCESS) {
73        return ret;
74    }
75    do {
76        ret = OH_CryptoDigest_Update(ctx, &in);
77        if (ret != CRYPTO_SUCCESS) {
78            break;
79        }
80        ret = OH_CryptoDigest_Final(ctx, &out);
81        if (ret != CRYPTO_SUCCESS) {
82            break;
83        }
84        mdLen = OH_CryptoDigest_GetLength(ctx);
85    } while (0);
86    OH_Crypto_FreeDataBlob(&out);
87    OH_DigestCrypto_Destroy(ctx);
88    return ret;
89}
90```
91
92### MD (Passing In Data by Segment)
93
941. Use [OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create) with the MD algorithm **SHA256** to generate an MD operation instance ([OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest)).
95
962. Call [OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update) multiple times to pass in 20 bytes each time.
97
983. Use [OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final) to generate an MD.
99
1004. Use [OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength) to obtain the MD length, in bytes.
101
1025. Use [OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy) to destroy the [OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest) instance.
103
104**Example**
105
106```c++
107#include <stdlib.h>
108#include "CryptoArchitectureKit/crypto_common.h"
109#include "CryptoArchitectureKit/crypto_digest.h"
110#define OH_CRYPTO_DIGEST_DATA_MAX (1024 * 1024 * 100)
111
112static OH_Crypto_ErrCode doLoopMd()
113{
114    OH_Crypto_ErrCode ret;
115    OH_CryptoDigest *ctx = nullptr;
116    uint8_t *testData = (uint8_t *)malloc(OH_CRYPTO_DIGEST_DATA_MAX);
117    Crypto_DataBlob out = {.data = nullptr, .len = 0};
118    int mdLen = 0;
119    int isBlockSize = 20;
120    int offset = 0;
121
122    ret = OH_CryptoDigest_Create("SHA256", &ctx);
123    if (ret != CRYPTO_SUCCESS) {
124        return ret;
125    }
126    do {
127        for (int i = 0; i < 640 / isBlockSize; i++) {
128            Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData + offset),
129                                .len = static_cast<size_t>(isBlockSize)};
130            ret = OH_CryptoDigest_Update(ctx, &in);
131            if (ret != CRYPTO_SUCCESS) {
132                break;
133            }
134            offset += isBlockSize;
135        }
136        ret = OH_CryptoDigest_Final(ctx, &out);
137        if (ret != CRYPTO_SUCCESS) {
138            break;
139        }
140        mdLen = OH_CryptoDigest_GetLength(ctx);
141    } while (0);
142    OH_Crypto_FreeDataBlob(&out);
143    OH_DigestCrypto_Destroy(ctx);
144    return ret;
145}
146```
147