1/*
2 * Copyright (C) 2024 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 */
15import { describe, it, expect, beforeAll } from '@ohos/hypium';
16import huks from '@ohos.security.huks';
17import { HuksCipherAES } from './cipher/publicCipherParam';
18import { HksTag } from './publicParam';
19import { stringToUint8Array, uint8ArrayToString, checkSoftwar, arrayEqual } from './publicFunc';
20import { Data64b } from '../data.json';
21let IV = '0000000000000000';
22let AAD = '0000000000000000';
23let NONCE = '00000000000';
24let AEAD = '0000000000000000';
25let useSoftware = true;
26
27let srcData63 = 'Hks_AES_Cipher_Test_000000000000000000000_string';
28let srcData63Kb = stringToUint8Array(srcData63);
29let srcData65 = 'Hks_AES_Cipher_Test_000000000000000000000000000000000000000_string';
30let srcData65Kb = stringToUint8Array(srcData65);
31let srcData64Kb = stringToUint8Array(Data64b)
32let updateResult = new Array();
33let finishData = new Array();
34let dataBeforeEncrypt = new Array();
35let handle;
36let res = true;
37
38async function publicInitFunc(srcKeyAlies, HuksOptions) {
39  console.info(`enter promise doInit`);
40  try {
41    await huks.initSession(srcKeyAlies, HuksOptions)
42      .then((data) => {
43        console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
44        handle = data.handle;
45      })
46      .catch(error => {
47        console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`);
48        res = false;
49      });
50  } catch (error) {
51    console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
52    res = false;
53  }
54}
55
56async function publicUpdateFunc(HuksOptions, thirdInderfaceName, isEncrypt) {
57  let dateSize = 64;
58  let huksOptionsInData = HuksOptions.inData;
59  let inDataArray = HuksOptions.inData;
60  if (Array.from(inDataArray).length < dateSize) {
61    await update(handle, HuksOptions);
62    HuksOptions.inData = new Uint8Array(new Array());
63    await publicFinishAbortFunc(HuksOptions, thirdInderfaceName, isEncrypt, 0);
64  } else {
65    let count = Math.floor(Array.from(inDataArray).length / dateSize);
66    let remainder = Array.from(inDataArray).length % dateSize;
67    for (let i = 0; i < count; i++) {
68      HuksOptions.inData = new Uint8Array(Array.from(huksOptionsInData).slice(dateSize * i, dateSize * (i + 1)));
69      await update(handle, HuksOptions);
70    }
71    HuksOptions.inData = huksOptionsInData;
72    if (remainder !== 0) {
73      HuksOptions.inData = new Uint8Array(
74        Array.from(huksOptionsInData).slice(dateSize * count, uint8ArrayToString(inDataArray).length)
75      );
76    } else {
77      HuksOptions.inData = new Uint8Array(new Array());
78    }
79    await publicFinishAbortFunc(HuksOptions, thirdInderfaceName, isEncrypt);
80  }
81}
82
83async function update(handle, HuksOptions) {
84  console.info(`enter promise doUpdate`);
85  try {
86    await huks.updateSession(handle, HuksOptions)
87      .then((data) => {
88        console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
89        if (updateResult.length !== 0) {
90          console.log(`test update outDatalength ${updateResult.length}`);
91          updateResult = updateResult.concat(Array.from(data.outData));
92        } else {
93          console.log(`test update outDatalength ${updateResult.length}`);
94          updateResult = Array.from(data.outData);
95        }
96      })
97      .catch(error => {
98        console.error(`promise: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
99        res = false;
100      });
101  } catch (error) {
102    console.error(`promise: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
103    res = false;
104  }
105}
106
107async function publicFinishAbortFunc(HuksOptions, thirdInderfaceName, isEncrypt) {
108  if (thirdInderfaceName == 'finish') {
109    await finish(HuksOptions, isEncrypt);
110  } else if (thirdInderfaceName == 'abort') {
111    await abort(HuksOptions);
112  }
113}
114
115async function finish(HuksOptions, isEncrypt) {
116  console.info(`enter promise doFinish`);
117  try {
118    await huks.finishSession(handle, HuksOptions)
119      .then((data) => {
120        console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
121        if (dataBeforeEncrypt.length > 64) {
122          finishData = uint8ArrayToString(updateResult.concat(Array.from(data.outData)));
123          updateResult = updateResult.concat(Array.from(data.outData));
124        } else {
125          console.info(`updateResult: updateResult success, data = ${JSON.stringify(updateResult)}`);
126          finishData = uint8ArrayToString(updateResult);
127        }
128      })
129      .catch(error => {
130        console.error(`promise: doFinish failed, code: ${error.code}, msg: ${error.message}`);
131        res = false;
132      });
133  } catch (error) {
134    console.error(`promise: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
135    res = false;
136  }
137}
138
139async function abort(HuksOptions) {
140  console.info(`enter promise doAbort`);
141  try {
142    await huks.abortSession(handle, HuksOptions)
143      .then((data) => {
144        console.info(`promise: doAbort success, data = ${JSON.stringify(data)}`);
145      })
146      .catch(error => {
147        console.error(`promise: doAbort failed, code: ${error.code}, msg: ${error.message}`);
148        res = false;
149      });
150  } catch (error) {
151    console.error(`promise: doAbort input arg invalid, code: ${error.code}, msg: ${error.message}`);
152    res = false;
153  }
154}
155
156async function publicDeleteKeyFunc(srcKeyAlies, genHuksOptionsNONECBC) {
157  console.info(`enter promise deleteKeyItem`);
158  try {
159    await huks.deleteKeyItem(srcKeyAlies, genHuksOptionsNONECBC)
160      .then((data) => {
161        console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
162      })
163      .catch(error => {
164        console.error(`promise: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
165        res = false;
166      });
167  } catch (error) {
168    console.error(`promise: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
169    res = false;
170  }
171}
172
173async function publicCipherFunc(srcKeyAlies, HuksOptions, thirdInderfaceName, isEncrypt) {
174  try {
175    updateResult = new Array();
176    if (isEncrypt) {
177      // await publicGenerateKeyFunc(srcKeyAlies);
178      dataBeforeEncrypt = HuksOptions.inData; //原始数据
179    }
180    await publicInitFunc(srcKeyAlies, HuksOptions);
181    await publicUpdateFunc(HuksOptions, thirdInderfaceName, isEncrypt);
182    if (!isEncrypt || (isEncrypt && thirdInderfaceName == 'abort')) {
183      await publicDeleteKeyFunc(srcKeyAlies, HuksOptions);
184    }
185  } catch (e) {
186    res = false;
187  }
188}
189
190
191async function checkAESChiper(srcKeyAliesFirst, srcKeyAliesSecond, HuksOptions) {
192  updateResult = new Array();
193  HuksOptions.inData = srcData64Kb;
194  HuksOptions.properties.splice(2, 1, HuksCipherAES.HuksKeyPurposeDECRYPT);
195  //加密
196  await publicCipherFunc(srcKeyAliesFirst, HuksOptions, 'finish', true);
197  //解密
198  HuksOptions.properties.splice(2, 1, HuksCipherAES.HuksKeyPurposeENCRYPT);
199  HuksOptions.inData = new Uint8Array(updateResult);
200  await publicCipherFunc(srcKeyAliesSecond, HuksOptions, 'finish', false);
201  // let arrayEqualRes = false;
202  let arrayEqualRes = arrayEqual(Array.from(updateResult), Array.from(srcData64Kb))
203  // console.info('arrayEqualRes is ' + arrayEqualRes);
204  if (!arrayEqualRes) { // if not success then res comes to false
205    res = false;
206  }
207
208  // console.info('res before return is ' + res);
209  return res;
210}
211
212export { checkAESChiper };