• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params);
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