1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 // [Start crypt_decrypt_sm4_gcm_seg]
17 #include <cstring>
18 #include "CryptoArchitectureKit/crypto_common.h"
19 #include "CryptoArchitectureKit/crypto_sym_cipher.h"
20
21 #define OH_CRYPTO_GCM_TAG_LEN 16
22 #define OH_CRYPTO_MAX_TEST_DATA_LEN 128
23
doTestSm4GcmSeg()24 OH_Crypto_ErrCode doTestSm4GcmSeg()
25 {
26 OH_CryptoSymKeyGenerator *genCtx = nullptr;
27 OH_CryptoSymCipher *encCtx = nullptr;
28 OH_CryptoSymCipher *decCtx = nullptr;
29 OH_CryptoSymKey *keyCtx = nullptr;
30 OH_CryptoSymCipherParams *params = nullptr;
31
32 char *plainText = const_cast<char *>("aaaaa.....bbbbb.....ccccc.....ddddd.....eee");
33 Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)};
34 uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8};
35 uint8_t tagArr[16] = {0};
36 uint8_t iv[12] = {1, 2, 4, 12, 3, 4, 2, 3, 3, 2, 0, 4}; // iv使用安全随机数生成
37 Crypto_DataBlob tag = {.data = nullptr, .len = 0};
38 Crypto_DataBlob ivBlob = {.data = iv, .len = sizeof(iv)};
39 Crypto_DataBlob aadBlob = {.data = aad, .len = sizeof(aad)};
40 Crypto_DataBlob outUpdate = {.data = nullptr, .len = 0};
41 Crypto_DataBlob decUpdate = {.data = nullptr, .len = 0};
42 Crypto_DataBlob tagInit = {.data = tagArr, .len = sizeof(tagArr)};
43 int32_t cipherLen = 0;
44 int blockSize = 20;
45 int32_t randomLen = strlen(plainText);
46 int cnt = randomLen / blockSize;
47 int rem = randomLen % blockSize;
48 uint8_t cipherText[OH_CRYPTO_MAX_TEST_DATA_LEN] = {0};
49 Crypto_DataBlob cipherBlob;
50
51 // 生成密钥
52 OH_Crypto_ErrCode ret = OH_CryptoSymKeyGenerator_Create("SM4_128", &genCtx);
53 if (ret != CRYPTO_SUCCESS) {
54 goto end;
55 }
56 ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx);
57 if (ret != CRYPTO_SUCCESS) {
58 goto end;
59 }
60
61 // 设置参数
62 ret = OH_CryptoSymCipherParams_Create(¶ms);
63 if (ret != CRYPTO_SUCCESS) {
64 goto end;
65 }
66 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivBlob);
67 if (ret != CRYPTO_SUCCESS) {
68 goto end;
69 }
70 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadBlob);
71 if (ret != CRYPTO_SUCCESS) {
72 goto end;
73 }
74 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagInit);
75 if (ret != CRYPTO_SUCCESS) {
76 goto end;
77 }
78
79 // 加密
80 ret = OH_CryptoSymCipher_Create("SM4_128|GCM|PKCS7", &encCtx);
81 if (ret != CRYPTO_SUCCESS) {
82 goto end;
83 }
84 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params);
85 if (ret != CRYPTO_SUCCESS) {
86 goto end;
87 }
88
89 for (int i = 0; i < cnt; i++) {
90 msgBlob.len = blockSize;
91 ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &outUpdate);
92 if (ret != CRYPTO_SUCCESS) {
93 goto end;
94 }
95 msgBlob.data += blockSize;
96 memcpy(&cipherText[cipherLen], outUpdate.data, outUpdate.len);
97 cipherLen += outUpdate.len;
98 }
99 if (rem > 0) {
100 msgBlob.len = rem;
101 ret = OH_CryptoSymCipher_Update(encCtx, (Crypto_DataBlob *)&msgBlob, &outUpdate);
102 if (ret != CRYPTO_SUCCESS) {
103 goto end;
104 }
105 memcpy(&cipherText[cipherLen], outUpdate.data, outUpdate.len);
106 cipherLen += outUpdate.len;
107 }
108 ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tag);
109 if (ret != CRYPTO_SUCCESS) {
110 goto end;
111 }
112
113 // 解密
114 cipherBlob = {.data = reinterpret_cast<uint8_t *>(cipherText), .len = (size_t)cipherLen};
115 msgBlob.data -= strlen(plainText) - rem;
116 msgBlob.len = strlen(plainText);
117 ret = OH_CryptoSymCipher_Create("SM4_128|GCM|PKCS7", &decCtx);
118 if (ret != CRYPTO_SUCCESS) {
119 goto end;
120 }
121 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tag);
122 if (ret != CRYPTO_SUCCESS) {
123 goto end;
124 }
125 ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params);
126 if (ret != CRYPTO_SUCCESS) {
127 goto end;
128 }
129 ret = OH_CryptoSymCipher_Final(decCtx, &cipherBlob, &decUpdate);
130 if (ret != CRYPTO_SUCCESS) {
131 goto end;
132 }
133 end:
134 OH_CryptoSymCipherParams_Destroy(params);
135 OH_CryptoSymCipher_Destroy(encCtx);
136 OH_CryptoSymCipher_Destroy(decCtx);
137 OH_CryptoSymKeyGenerator_Destroy(genCtx);
138 OH_CryptoSymKey_Destroy(keyCtx);
139 OH_Crypto_FreeDataBlob(&outUpdate);
140 OH_Crypto_FreeDataBlob(&tag);
141 OH_Crypto_FreeDataBlob(&decUpdate);
142 return ret;
143 }
144 // [End crypt_decrypt_sm4_gcm_seg]
145