1# Encryption and Decryption with an AES Symmetric Key (CCM Mode) (C/C++) 2 3 4For details about the algorithm specifications, see [AES](crypto-sym-encrypt-decrypt-spec.md#aes). 5 6 7## Adding the Dynamic Library in the CMake Script 8```txt 9target_link_libraries(entry PUBLIC libohcrypto.so) 10``` 11 12## How to Develop 13 14**Creating an Object** 15 16Call [OH_CryptoSymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_create) and [OH_CryptoSymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_generate) to generate a 128-bit AES symmetric key (**OH_CryptoSymKey**). 17 18In addition to the example in this topic, [AES](crypto-sym-key-generation-conversion-spec.md#aes) and [Randomly Generating a Symmetric Key](crypto-generate-sym-key-randomly-ndk.md) may help you better understand how to generate an AES symmetric key. Note that the input parameters in the reference documents may be different from those in the example below. 19 20**Encrypting a Message** 21 221. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_create) with the string parameter **'AES128|CCM'** to create a **Cipher** instance for encryption. The key type is AES128, and the block cipher mode is CCM. 23 242. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_create) to create a symmetric cipher parameter instance, and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam) to set cipher parameters. 25 263. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_ENCRYPT_MODE**, and specify the key for encryption (**OH_CryptoSymKey**) and the encryption parameter instance (**OH_CryptoSymCipherParams**) corresponding to the CCM mode. 27 284. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update) to update the data (plaintext) to be encrypted. 29 30 Currently, the amount of data to be passed in by a single **update()** call is not limited. You can determine how to pass in data based on the data size. 31 > **NOTE**<br> 32 > The CCM mode does not support segment-based encryption and decryption. 33 345. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final) to generate the ciphertext. 35 - If data has been passed in by **OH_CryptoSymCipher_Update**, pass in **null** in the **data** parameter of **OH_CryptoSymCipher_Final**. 36 - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 37 > **NOTE**<br> 38 > If CCM mode is used, **authTag** is set in **final()** as the authentication information initialized during decryption and needs to be saved. 39 406. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_create) to create a **Params** instance, and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam) to set **authTag** as the authentication information for decryption. 41 42 In CCM mode, **authTag** must be of 12 bytes. It is used as the authentication information during decryption. In the example, **authTag** is of 12 bytes. 43 44 45 46 47**Decrypting a Message** 48 491. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_create) with the string parameter **'AES128|CCM'** to create a **Cipher** instance for decryption. The key type is AES128, and the block cipher mode is CCM. 50 512. Call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam) to set **authTag**, which must be the same as that set in encryption. 52 533. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_DECRYPT_MODE**, and specify the key for decryption (**OH_CryptoSymKey**) and the decryption parameter instance (**OH_CryptoSymCipherParams**) corresponding to the CCM mode. 54 554. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update) to update the data (ciphertext) to be decrypted. 56 57 Currently, the amount of data to be passed in by a single **update()** call is not limited. You can determine how to pass in data based on the data size. 58 > **NOTE**<br> 59 > The CCM mode does not support segment-based encryption and decryption. 60 614. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final) to generate the plaintext. 62 - If data has been passed in by **OH_CryptoSymCipher_Update**, pass in **null** in the **data** parameter of **OH_CryptoSymCipher_Final**. 63 - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 64 65**Destroying Objects** 66 67Call [OH_CryptoSymKeyGenerator_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_destroy), [OH_CryptoSymCipher_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_destroy), [OH_CryptoSymKey_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkey_destroy) and [OH_Crypto_FreeDataBlob](../../reference/apis-crypto-architecture-kit/_crypto_common_api.md#oh_crypto_freedatablob) to release the allocated memory and destroy the symmetric key, **Cipher** instance, and **Params**. 68 69**Example ** 70 71```c++ 72#include "CryptoArchitectureKit/crypto_common.h" 73#include "CryptoArchitectureKit/crypto_sym_cipher.h" 74#include <string.h> 75 76static OH_Crypto_ErrCode doTestAesCcm() 77{ 78 OH_CryptoSymKeyGenerator *genCtx = nullptr; 79 OH_CryptoSymCipher *encCtx = nullptr; 80 OH_CryptoSymCipher *decCtx = nullptr; 81 OH_CryptoSymKey *keyCtx = nullptr; 82 OH_CryptoSymCipherParams *params = nullptr; 83 84 Crypto_DataBlob encData = {.data = nullptr, .len = 0}; 85 Crypto_DataBlob decData = {.data = nullptr, .len = 0}; 86 87 uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8}; // The aad value in the sample code is for reference only. 88 uint8_t tag[12] = {0}; 89 uint8_t iv[7] = {1, 2, 4, 12, 3, 4, 2}; // The iv value in the sample code is for reference only. 90 Crypto_DataBlob ivData = {.data = iv, .len = sizeof(iv)}; 91 Crypto_DataBlob aadData = {.data = aad, .len = sizeof(aad)}; 92 Crypto_DataBlob tagData = {.data = tag, .len = sizeof(tag)}; 93 Crypto_DataBlob tagOutPut = {.data = nullptr, .len = 0}; 94 char *plainText = const_cast<char *>("this is test!"); 95 Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)}; 96 // Generate a symmetric key. 97 OH_Crypto_ErrCode ret; 98 ret = OH_CryptoSymKeyGenerator_Create("AES128", &genCtx); 99 if (ret != CRYPTO_SUCCESS) { 100 goto end; 101 } 102 ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx); 103 if (ret != CRYPTO_SUCCESS) { 104 goto end; 105 } 106 107 // Set parameters. 108 ret = OH_CryptoSymCipherParams_Create(¶ms); 109 if (ret != CRYPTO_SUCCESS) { 110 goto end; 111 } 112 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivData); 113 if (ret != CRYPTO_SUCCESS) { 114 goto end; 115 } 116 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadData); 117 if (ret != CRYPTO_SUCCESS) { 118 goto end; 119 } 120 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagData); 121 if (ret != CRYPTO_SUCCESS) { 122 goto end; 123 } 124 125 // Encrypt data. 126 ret = OH_CryptoSymCipher_Create("AES128|CCM", &encCtx); 127 if (ret != CRYPTO_SUCCESS) { 128 goto end; 129 } 130 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params); 131 if (ret != CRYPTO_SUCCESS) { 132 goto end; 133 } 134 ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &encData); 135 if (ret != CRYPTO_SUCCESS) { 136 goto end; 137 } 138 ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tagOutPut); 139 if (ret != CRYPTO_SUCCESS) { 140 goto end; 141 } 142 143 // Decrypt data. 144 ret = OH_CryptoSymCipher_Create("AES128|CCM", &decCtx); 145 if (ret != CRYPTO_SUCCESS) { 146 goto end; 147 } 148 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagOutPut); 149 if (ret != CRYPTO_SUCCESS) { 150 goto end; 151 } 152 ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params); 153 if (ret != CRYPTO_SUCCESS) { 154 goto end; 155 } 156 ret = OH_CryptoSymCipher_Update(decCtx, &encData, &decData); 157 if (ret != CRYPTO_SUCCESS) { 158 goto end; 159 } 160 ret = OH_CryptoSymCipher_Final(decCtx, nullptr, &decData); 161 if (ret != CRYPTO_SUCCESS) { 162 goto end; 163 } 164 165end: 166 OH_CryptoSymCipherParams_Destroy(params); 167 OH_CryptoSymCipher_Destroy(encCtx); 168 OH_CryptoSymCipher_Destroy(decCtx); 169 OH_CryptoSymKeyGenerator_Destroy(genCtx); 170 OH_CryptoSymKey_Destroy(keyCtx); 171 OH_Crypto_FreeDataBlob(&encData); 172 OH_Crypto_FreeDataBlob(&decData); 173 OH_Crypto_FreeDataBlob(&tagOutPut); 174 return ret; 175} 176``` 177