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