* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "crypto_sym_cipher.h"
#include "memory.h"
#include <stdlib.h>
#include "sym_key_generator.h"
#include "crypto_common.h"
#include "cipher.h"
#include "blob.h"
#include "object_base.h"
#include "result.h"
#include "native_common.h"
struct OH_CryptoSymCipher {
HcfObjectBase base;
HcfResult (*init)(HcfCipher *self, enum HcfCryptoMode opMode,
HcfKey *key, HcfParamsSpec *params);
HcfResult (*update)(HcfCipher *self, HcfBlob *input, HcfBlob *output);
HcfResult (*doFinal)(HcfCipher *self, HcfBlob *input, HcfBlob *output);
const char *(*getAlgorithm)(HcfCipher *self);
HcfResult (*setCipherSpecUint8Array)(HcfCipher *self, CipherSpecItem item, HcfBlob blob);
HcfResult (*getCipherSpecString)(HcfCipher *self, CipherSpecItem item, char **returnString);
HcfResult (*getCipherSpecUint8Array)(HcfCipher *self, CipherSpecItem item, HcfBlob *returnUint8Array);
};
struct OH_CryptoSymCipherParams {
HcfParamsSpec base;
HcfBlob iv;
HcfBlob aad;
HcfBlob tag;
};
struct OH_CryptoSymKey {
HcfKey key;
void (*clearMem)(HcfSymKey *self);
};
static OH_Crypto_ErrCode CryptoSymCipherParamsCreate(OH_CryptoSymCipherParams **params)
{
if (params == NULL) {
return CRYPTO_INVALID_PARAMS;
}
*params = (OH_CryptoSymCipherParams *)HcfMalloc(sizeof(OH_CryptoSymCipherParams), 0);
if (*params == NULL) {
return CRYPTO_MEMORY_ERROR;
}
return CRYPTO_SUCCESS;
}
OH_Crypto_ErrCode OH_CryptoSymCipherParams_Create(OH_CryptoSymCipherParams **params)
{
return CryptoSymCipherParamsCreate(params);
}
static OH_Crypto_ErrCode CryptoSymCipherParamsSetParam(OH_CryptoSymCipherParams *params,
CryptoSymCipher_ParamsType paramsType, Crypto_DataBlob *value)
{
if ((params == NULL) || (value == NULL)) {
return CRYPTO_INVALID_PARAMS;
}
switch (paramsType) {
case CRYPTO_IV_DATABLOB:
params->iv.data = value->data;
params->iv.len = value->len;
break;
case CRYPTO_AAD_DATABLOB:
params->aad.data = value->data;
params->aad.len = value->len;
break;
case CRYPTO_TAG_DATABLOB:
params->tag.data = value->data;
params->tag.len = value->len;
break;
default:
return CRYPTO_INVALID_PARAMS;
}
return CRYPTO_SUCCESS;
}
OH_Crypto_ErrCode OH_CryptoSymCipherParams_SetParam(OH_CryptoSymCipherParams *params,
CryptoSymCipher_ParamsType paramsType, Crypto_DataBlob *value)
{
return CryptoSymCipherParamsSetParam(params, paramsType, value);
}
static void CryptoSymCipherParamsDestroy(OH_CryptoSymCipherParams *params)
{
if (params == NULL) {
return;
}
HcfFree(params);
}
void OH_CryptoSymCipherParams_Destroy(OH_CryptoSymCipherParams *params)
{
CryptoSymCipherParamsDestroy(params);
}
static OH_Crypto_ErrCode CryptoSymCipherCreate(const char *algoName, OH_CryptoSymCipher **ctx)
{
if (ctx == NULL) {
return CRYPTO_INVALID_PARAMS;
}
HcfResult ret = HcfCipherCreate(algoName, (HcfCipher **)ctx);
return GetOhCryptoErrCode(ret);
}
OH_Crypto_ErrCode OH_CryptoSymCipher_Create(const char *algoName, OH_CryptoSymCipher **ctx)
{
return CryptoSymCipherCreate(algoName, ctx);
}
static OH_Crypto_ErrCode CryptoSymCipherInit(OH_CryptoSymCipher *ctx, Crypto_CipherMode mod,
OH_CryptoSymKey *key, OH_CryptoSymCipherParams *params)
{
if ((ctx == NULL) || (ctx->init == NULL) || (key == NULL)) {
return CRYPTO_INVALID_PARAMS;
}
HcfResult ret = ctx->init((HcfCipher *)ctx, (enum HcfCryptoMode)mod, (HcfKey *)key, (HcfParamsSpec *)params);
return GetOhCryptoErrCode(ret);
}
OH_Crypto_ErrCode OH_CryptoSymCipher_Init(OH_CryptoSymCipher *ctx, Crypto_CipherMode mod,
OH_CryptoSymKey *key, OH_CryptoSymCipherParams *params)
{
return CryptoSymCipherInit(ctx, mod, key, params);
}
static OH_Crypto_ErrCode CryptoSymCipherUpdate(OH_CryptoSymCipher *ctx, Crypto_DataBlob *in, Crypto_DataBlob *out)
{
if ((ctx == NULL) || (ctx->update == NULL) || (in == NULL) || (out == NULL)) {
return CRYPTO_INVALID_PARAMS;
}
HcfResult ret = ctx->update((HcfCipher *)ctx, (HcfBlob *)in, (HcfBlob *)out);
return GetOhCryptoErrCode(ret);
}
OH_Crypto_ErrCode OH_CryptoSymCipher_Update(OH_CryptoSymCipher *ctx, Crypto_DataBlob *in, Crypto_DataBlob *out)
{
return CryptoSymCipherUpdate(ctx, in, out);
}
static OH_Crypto_ErrCode CryptoSymCipherFinal(OH_CryptoSymCipher *ctx, Crypto_DataBlob *in, Crypto_DataBlob *out)
{
if ((ctx == NULL) || (ctx->doFinal == NULL) || (out == NULL)) {
return CRYPTO_INVALID_PARAMS;
}
HcfResult ret = ctx->doFinal((HcfCipher *)ctx, (HcfBlob *)in, (HcfBlob *)out);
return GetOhCryptoErrCode(ret);
}
OH_Crypto_ErrCode OH_CryptoSymCipher_Final(OH_CryptoSymCipher *ctx, Crypto_DataBlob *in, Crypto_DataBlob *out)
{
return CryptoSymCipherFinal(ctx, in, out);
}
static const char *CryptoSymCipherGetAlgoName(OH_CryptoSymCipher *ctx)
{
if ((ctx == NULL) || (ctx->getAlgorithm == NULL)) {
return NULL;
}
return ctx->getAlgorithm((HcfCipher *)ctx);
}
const char *OH_CryptoSymCipher_GetAlgoName(OH_CryptoSymCipher *ctx)
{
const char *name = CryptoSymCipherGetAlgoName(ctx);
return name;
}
static void CryptoSymCipherDestroy(OH_CryptoSymCipher *ctx)
{
if ((ctx == NULL) || (ctx->base.destroy == NULL)) {
return;
}
ctx->base.destroy((HcfObjectBase *)ctx);
}
void OH_CryptoSymCipher_Destroy(OH_CryptoSymCipher *ctx)
{
CryptoSymCipherDestroy(ctx);
}