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