1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include "crypt_eal_cipher.h" // Header file of the interfaces for symmetric encryption and decryption.
21 #include "bsl_sal.h"
22 #include "bsl_err.h"
23 #include "crypt_algid.h" // Algorithm ID list.
24 #include "crypt_errno.h" // Error code list.
25
StdMalloc(uint32_t len)26 void *StdMalloc(uint32_t len) {
27 return malloc((size_t)len);
28 }
29
PrintLastError(void)30 void PrintLastError(void) {
31 const char *file = NULL;
32 uint32_t line = 0;
33 BSL_ERR_GetLastErrorFileLine(&file, &line); // Obtain the name and number of lines of the error file.
34 printf("failed at file %s at line %d\n", file, line);
35 }
36
main(void)37 int main(void)
38 {
39 uint8_t data[10] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x1c, 0x14};
40 uint8_t iv[16] = {0};
41 uint8_t key[16] = {0};
42 uint32_t dataLen = sizeof(data);
43 uint8_t cipherText[100];
44 uint8_t plainText[100];
45 uint32_t outTotalLen = 0;
46 uint32_t outLen = sizeof(cipherText);
47 uint32_t cipherTextLen;
48 int32_t ret;
49
50 printf("plain text to be encrypted: ");
51 for (uint32_t i = 0; i < dataLen; i++) {
52 printf("%02x", data[i]);
53 }
54 printf("\n");
55
56 // Initialize the error code module.
57 BSL_ERR_Init();
58
59 /**
60 * Before calling the algorithm APIs,
61 * call the BSL_SAL_CallBack_Ctrl function to register the malloc and free functions.
62 * Execute this step only once. If the memory allocation ability of Linux is available,
63 * the two functions can be registered using Linux by default.
64 */
65 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc);
66 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free);
67
68 // Create a context.
69 CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC);
70 if (ctx == NULL) {
71 PrintLastError();
72 BSL_ERR_DeInit();
73 return 1;
74 }
75 /*
76 * During initialization, the last input parameter can be true or false. true indicates encryption,
77 * and false indicates decryption.
78 */
79 ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true);
80 if (ret != CRYPT_SUCCESS) {
81 // Output the error code. You can find the error information in **crypt_errno.h** based on the error code.
82 printf("error code is %x\n", ret);
83 PrintLastError();
84 goto EXIT;
85 }
86 // Set the padding mode.
87 ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7);
88 if (ret != CRYPT_SUCCESS) {
89 printf("error code is %x\n", ret);
90 PrintLastError();
91 goto EXIT;
92 }
93 /**
94 * Enter the data to be calculated. This interface can be called for multiple times.
95 * The input value of **outLen** is the length of the ciphertext,
96 * and the output value is the amount of processed data.
97 *
98 */
99 ret = CRYPT_EAL_CipherUpdate(ctx, data, dataLen, cipherText, &outLen);
100 if (ret != CRYPT_SUCCESS) {
101 printf("error code is %x\n", ret);
102 PrintLastError();
103 goto EXIT;
104 }
105
106 outTotalLen += outLen;
107 outLen = sizeof(cipherText) - outTotalLen;
108
109 ret = CRYPT_EAL_CipherFinal(ctx, cipherText + outTotalLen, &outLen);
110 if (ret != CRYPT_SUCCESS) {
111 printf("error code is %x\n", ret);
112 PrintLastError();
113 goto EXIT;
114 }
115
116 outTotalLen += outLen;
117 printf("cipher text value is: ");
118
119 for (uint32_t i = 0; i < outTotalLen; i++) {
120 printf("%02x", cipherText[i]);
121 }
122 printf("\n");
123
124 // Start decryption.
125 cipherTextLen = outTotalLen;
126 outTotalLen = 0;
127 outLen = sizeof(plainText);
128
129 // When initializing the decryption function, set the last input parameter to false.
130 ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), false);
131 if (ret != CRYPT_SUCCESS) {
132 printf("error code is %x\n", ret);
133 PrintLastError();
134 goto EXIT;
135 }
136
137 // Set the padding mode, which must be the same as that for encryption.
138 ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7);
139 if (ret != CRYPT_SUCCESS) {
140 printf("error code is %x\n", ret);
141 PrintLastError();
142 goto EXIT;
143 }
144
145 // Enter the ciphertext data.
146 ret = CRYPT_EAL_CipherUpdate(ctx, cipherText, cipherTextLen, plainText, &outLen);
147 if (ret != CRYPT_SUCCESS) {
148 printf("error code is %x\n", ret);
149 PrintLastError();
150 goto EXIT;
151 }
152 outTotalLen += outLen;
153 outLen = sizeof(plainText) - outTotalLen;
154
155 // Decrypt the last segment of data and remove the filled content.
156 ret = CRYPT_EAL_CipherFinal(ctx, plainText + outTotalLen, &outLen);
157 if (ret != CRYPT_SUCCESS) {
158 printf("error code is %x\n", ret);
159 PrintLastError();
160 goto EXIT;
161 }
162
163 outTotalLen += outLen;
164
165 printf("decrypted plain text value is: ");
166 for (uint32_t i = 0; i < outTotalLen; i++) {
167 printf("%02x", plainText[i]);
168 }
169 printf("\n");
170
171 if (outTotalLen != dataLen || memcmp(plainText, data, dataLen) != 0) {
172 printf("plaintext comparison failed\n");
173 goto EXIT;
174 }
175 printf("pass \n");
176
177 EXIT:
178 CRYPT_EAL_CipherFreeCtx(ctx);
179 BSL_ERR_DeInit();
180 return ret;
181 }