1# Encryption and Decryption with an AES Symmetric Key (CCM Mode) (C/C++) 2 3<!--Kit: Crypto Architecture Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @zxz--3--> 6<!--Designer: @lanming--> 7<!--Tester: @PAFT--> 8<!--Adviser: @zengyawen--> 9 10For details, see [AES](crypto-sym-encrypt-decrypt-spec.md#aes). 11 12## Adding the Dynamic Library in the CMake Script 13```txt 14target_link_libraries(entry PUBLIC libohcrypto.so) 15``` 16 17## How to Develop 18 19**Creating an Object** 20 21Call [OH_CryptoSymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_create) and [OH_CryptoSymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_generate) to generate a symmetric key (**OH_CryptoSymKey**) with the key algorithm being AES and the key length being 128 bits. 22 23 In 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. 24 25**Encrypting a Message** 26 271. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.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. 28 292. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_create) to create a parameter object and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_setparam) to set encryption parameters. 30 313. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.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. 32 334. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in plaintext). 34 35 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. 36 > **NOTE**<br> 37 > The CCM mode does not support segment-based encryption and decryption. 38 395. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the encrypted data. 40 - If data has been passed in by **update()**, pass in **null** in the **data** parameter. 41 - Since **final()** might return **null**, always check its output before accessing any data. 42 > **NOTE**<br> 43 > If CCM mode is used, **authTag** is set in **final()** as the authentication information initialized during decryption and needs to be saved. 44 456. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_create) to create a **Params** instance, and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_setparam) to set **authTag** as the authentication information for decryption. 46 47 In CCM mode, the algorithm library supports only 12-byte **authTag**, which is used for initialization authentication during decryption. In the following example, **authTag** is of 12 bytes. 48 49**Decrypting a Message** 50 511. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_create) with the parameter **'AES128|CCM'** to create a **Cipher** instance for decryption. The key type is AES128, and the block cipher mode is CCM. 52 532. Before decryption, call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_setparam) to set **authTag** as the authentication information for initialization. 54 553. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to decryption mode, and specify the decryption key and the decryption parameter of the CCM mode. 56 574. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in ciphertext). 58 59 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 ciphertext size. 60 > **NOTE**<br> 61 > The CCM mode does not support segment-based encryption and decryption. 62 635. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the decrypted data. 64 - If data has been passed in by **update()**, pass in **null** in the **data** parameter. 65 - Before accessing the **final()** output data, check whether the result is **null** to avoid exceptions. 66 67**Destroying Objects** 68 69Call [OH_CryptoSymKeyGenerator_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_destroy), [OH_CryptoSymCipher_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_destroy), [OH_CryptoSymKey_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkey_destroy), and [OH_Crypto_FreeDataBlob](../../reference/apis-crypto-architecture-kit/capi-crypto-common-h.md#oh_crypto_freedatablob) to release the allocated memory and destroy the symmetric key, cipher instance, and parameters. 70 71- **Example** 72 73```c++ 74#include "CryptoArchitectureKit/crypto_common.h" 75#include "CryptoArchitectureKit/crypto_sym_cipher.h" 76#include <string.h> 77 78static OH_Crypto_ErrCode doTestAesCcm() 79{ 80 OH_CryptoSymKeyGenerator *genCtx = nullptr; 81 OH_CryptoSymCipher *encCtx = nullptr; 82 OH_CryptoSymCipher *decCtx = nullptr; 83 OH_CryptoSymKey *keyCtx = nullptr; 84 OH_CryptoSymCipherParams *params = nullptr; 85 86 Crypto_DataBlob encData = {.data = nullptr, .len = 0}; 87 Crypto_DataBlob decData = {.data = nullptr, .len = 0}; 88 89 uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8}; // The aad value in the sample code is for reference only. 90 uint8_t tag[12] = {0}; 91 uint8_t iv[7] = {1, 2, 4, 12, 3, 4, 2}; // The iv value in the sample code is for reference only. 92 Crypto_DataBlob ivData = {.data = iv, .len = sizeof(iv)}; 93 Crypto_DataBlob aadData = {.data = aad, .len = sizeof(aad)}; 94 Crypto_DataBlob tagData = {.data = tag, .len = sizeof(tag)}; 95 Crypto_DataBlob tagOutPut = {.data = nullptr, .len = 0}; 96 char *plainText = const_cast<char *>("this is test!"); 97 Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)}; 98 // Generate a symmetric key. 99 OH_Crypto_ErrCode ret; 100 ret = OH_CryptoSymKeyGenerator_Create("AES128", &genCtx); 101 if (ret != CRYPTO_SUCCESS) { 102 goto end; 103 } 104 ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx); 105 if (ret != CRYPTO_SUCCESS) { 106 goto end; 107 } 108 109 // Set parameters. 110 ret = OH_CryptoSymCipherParams_Create(¶ms); 111 if (ret != CRYPTO_SUCCESS) { 112 goto end; 113 } 114 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivData); 115 if (ret != CRYPTO_SUCCESS) { 116 goto end; 117 } 118 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadData); 119 if (ret != CRYPTO_SUCCESS) { 120 goto end; 121 } 122 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagData); 123 if (ret != CRYPTO_SUCCESS) { 124 goto end; 125 } 126 127 // Encrypt the message. 128 ret = OH_CryptoSymCipher_Create("AES128|CCM", &encCtx); 129 if (ret != CRYPTO_SUCCESS) { 130 goto end; 131 } 132 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params); 133 if (ret != CRYPTO_SUCCESS) { 134 goto end; 135 } 136 ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &encData); 137 if (ret != CRYPTO_SUCCESS) { 138 goto end; 139 } 140 ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tagOutPut); 141 if (ret != CRYPTO_SUCCESS) { 142 goto end; 143 } 144 145 // Decrypt the message. 146 ret = OH_CryptoSymCipher_Create("AES128|CCM", &decCtx); 147 if (ret != CRYPTO_SUCCESS) { 148 goto end; 149 } 150 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagOutPut); 151 if (ret != CRYPTO_SUCCESS) { 152 goto end; 153 } 154 ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params); 155 if (ret != CRYPTO_SUCCESS) { 156 goto end; 157 } 158 ret = OH_CryptoSymCipher_Update(decCtx, &encData, &decData); 159 if (ret != CRYPTO_SUCCESS) { 160 goto end; 161 } 162 ret = OH_CryptoSymCipher_Final(decCtx, nullptr, &decData); 163 if (ret != CRYPTO_SUCCESS) { 164 goto end; 165 } 166 167end: 168 OH_CryptoSymCipherParams_Destroy(params); 169 OH_CryptoSymCipher_Destroy(encCtx); 170 OH_CryptoSymCipher_Destroy(decCtx); 171 OH_CryptoSymKeyGenerator_Destroy(genCtx); 172 OH_CryptoSymKey_Destroy(keyCtx); 173 OH_Crypto_FreeDataBlob(&encData); 174 OH_Crypto_FreeDataBlob(&decData); 175 OH_Crypto_FreeDataBlob(&tagOutPut); 176 return ret; 177} 178``` 179