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