diff options
Diffstat (limited to 'src/mscng/kw_aes.c')
-rw-r--r-- | src/mscng/kw_aes.c | 702 |
1 files changed, 702 insertions, 0 deletions
diff --git a/src/mscng/kw_aes.c b/src/mscng/kw_aes.c new file mode 100644 index 00000000..4c52a952 --- /dev/null +++ b/src/mscng/kw_aes.c @@ -0,0 +1,702 @@ +/* + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2018 Miklos Vajna. All Rights Reserved. + */ +/** + * SECTION:kw_aes + * @Short_description: AES Key Transport transforms implementation for Microsoft Cryptography API: Next Generation (CNG). + * @Stability: Private + * + */ + +#include "globals.h" + +#ifndef XMLSEC_NO_AES + +#include <string.h> + +#define WIN32_NO_STATUS +#include <windows.h> +#undef WIN32_NO_STATUS +#include <ntstatus.h> +#include <bcrypt.h> +#include <ncrypt.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> +#include <xmlsec/bn.h> + +#include <xmlsec/mscng/crypto.h> + +#include "../kw_aes_des.h" + +/************************************************************************** + * + * Internal MSCng KW AES cipher CTX + * + *****************************************************************************/ +typedef struct _xmlSecMSCngKWAesCtx xmlSecMSCngKWAesCtx, *xmlSecMSCngKWAesCtxPtr; +struct _xmlSecMSCngKWAesCtx { + LPCWSTR pszAlgId; + xmlSecKeyDataId keyId; + xmlSecSize keySize; + xmlSecBuffer keyBuffer; +}; + +/****************************************************************************** + * + * KW AES transforms + * + * xmlSecMSCngKWAesCtx block is located after xmlSecTransform structure + * + *****************************************************************************/ +#define xmlSecMSCngKWAesSize \ + (sizeof(xmlSecTransform) + sizeof(xmlSecMSCngKWAesCtx)) +#define xmlSecMSCngKWAesGetCtx(transform) \ + ((xmlSecMSCngKWAesCtxPtr)(((unsigned char*)(transform)) + sizeof(xmlSecTransform))) + +/********************************************************************* + * + * AES KW implementation + * + ********************************************************************/ +static int +xmlSecMSCngKWAesBlockEncrypt(const xmlSecByte * in, xmlSecSize inSize, + xmlSecByte * out, xmlSecSize outSize, void * context) { + xmlSecMSCngKWAesCtxPtr ctx = (xmlSecMSCngKWAesCtxPtr)context; + BCRYPT_ALG_HANDLE hAlg = NULL; + BCRYPT_KEY_HANDLE hKey = NULL; + DWORD cbData; + PBYTE pbKeyObject = NULL; + DWORD cbKeyObject; + xmlSecBuffer blob; + BCRYPT_KEY_DATA_BLOB_HEADER* blobHeader; + xmlSecSize blobHeaderLen; + int res = -1; + NTSTATUS status; + int ret; + + xmlSecAssert2(in != NULL, -1); + xmlSecAssert2(inSize >= XMLSEC_KW_AES_BLOCK_SIZE, -1); + xmlSecAssert2(out != NULL, -1); + xmlSecAssert2(outSize >= inSize, -1); + xmlSecAssert2(ctx != NULL, -1); + xmlSecAssert2(xmlSecBufferGetSize(&ctx->keyBuffer) == ctx->keySize, -1); + + ret = xmlSecBufferInitialize(&blob, 0); + if(ret < 0) { + xmlSecInternalError("xmlSecBufferInitialize", NULL); + goto done; + } + + status = BCryptOpenAlgorithmProvider( + &hAlg, + BCRYPT_AES_ALGORITHM, + NULL, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptOpenAlgorithmProvider", NULL, status); + goto done; + } + + /* allocate the key object */ + status = BCryptGetProperty(hAlg, + BCRYPT_OBJECT_LENGTH, + (PBYTE)&cbKeyObject, + sizeof(DWORD), + &cbData, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptGetProperty", NULL, status); + goto done; + } + + pbKeyObject = xmlMalloc(cbKeyObject); + if(pbKeyObject == NULL) { + xmlSecMallocError(cbKeyObject, NULL); + goto done; + } + + /* prefix the key with a BCRYPT_KEY_DATA_BLOB_HEADER */ + blobHeaderLen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + xmlSecBufferGetSize(&ctx->keyBuffer); + ret = xmlSecBufferSetSize(&blob, blobHeaderLen); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferSetSize", NULL, "size=%d", + blobHeaderLen); + goto done; + } + + blobHeader = (BCRYPT_KEY_DATA_BLOB_HEADER*)xmlSecBufferGetData(&blob); + blobHeader->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + blobHeader->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + blobHeader->cbKeyData = xmlSecBufferGetSize(&ctx->keyBuffer); + memcpy(xmlSecBufferGetData(&blob) + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), + xmlSecBufferGetData(&ctx->keyBuffer), + xmlSecBufferGetSize(&ctx->keyBuffer)); + + /* perform the actual import */ + status = BCryptImportKey(hAlg, + NULL, + BCRYPT_KEY_DATA_BLOB, + &hKey, + pbKeyObject, + cbKeyObject, + xmlSecBufferGetData(&blob), + xmlSecBufferGetSize(&blob), + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptImportKey", NULL, status); + goto done; + } + + /* handle padding ourselves */ + if(out != in) { + memcpy(out, in, inSize); + } + + cbData = inSize; + status = BCryptEncrypt(hKey, + (PUCHAR)in, + inSize, + NULL, + NULL, + 0, + out, + inSize, + &cbData, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptEncrypt", NULL, status); + goto done; + } + + res = cbData; + +done: + if (hKey != NULL) { + BCryptDestroyKey(hKey); + } + + xmlSecBufferFinalize(&blob); + + if (pbKeyObject != NULL) { + xmlFree(pbKeyObject); + } + + if(hAlg != NULL) { + BCryptCloseAlgorithmProvider(hAlg, 0); + } + + return(res); +} + +static int +xmlSecMSCngKWAesBlockDecrypt(const xmlSecByte * in, xmlSecSize inSize, + xmlSecByte * out, xmlSecSize outSize, void * context) { + xmlSecMSCngKWAesCtxPtr ctx = (xmlSecMSCngKWAesCtxPtr)context; + BCRYPT_ALG_HANDLE hAlg = NULL; + BCRYPT_KEY_HANDLE hKey = NULL; + DWORD cbData; + PBYTE pbKeyObject = NULL; + DWORD cbKeyObject; + xmlSecBuffer blob; + BCRYPT_KEY_DATA_BLOB_HEADER* blobHeader; + xmlSecSize blobHeaderLen; + int res = -1; + NTSTATUS status; + int ret; + + xmlSecAssert2(in != NULL, -1); + xmlSecAssert2(inSize >= XMLSEC_KW_AES_BLOCK_SIZE, -1); + xmlSecAssert2(out != NULL, -1); + xmlSecAssert2(outSize >= inSize, -1); + xmlSecAssert2(ctx != NULL, -1); + xmlSecAssert2(xmlSecBufferGetSize(&ctx->keyBuffer) == ctx->keySize, -1); + + ret = xmlSecBufferInitialize(&blob, 0); + if(ret < 0) { + xmlSecInternalError("xmlSecBufferInitialize", NULL); + goto done; + } + + status = BCryptOpenAlgorithmProvider( + &hAlg, + BCRYPT_AES_ALGORITHM, + NULL, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptOpenAlgorithmProvider", NULL, status); + goto done; + } + + /* allocate the key object */ + status = BCryptGetProperty(hAlg, + BCRYPT_OBJECT_LENGTH, + (PBYTE)&cbKeyObject, + sizeof(DWORD), + &cbData, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptGetProperty", NULL, status); + goto done; + } + + pbKeyObject = xmlMalloc(cbKeyObject); + if(pbKeyObject == NULL) { + xmlSecMallocError(cbKeyObject, NULL); + goto done; + } + + /* prefix the key with a BCRYPT_KEY_DATA_BLOB_HEADER */ + blobHeaderLen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + xmlSecBufferGetSize(&ctx->keyBuffer); + ret = xmlSecBufferSetSize(&blob, blobHeaderLen); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferSetSize", NULL, "size=%d", + blobHeaderLen); + goto done; + } + + blobHeader = (BCRYPT_KEY_DATA_BLOB_HEADER*)xmlSecBufferGetData(&blob); + blobHeader->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + blobHeader->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + blobHeader->cbKeyData = xmlSecBufferGetSize(&ctx->keyBuffer); + memcpy(xmlSecBufferGetData(&blob) + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), + xmlSecBufferGetData(&ctx->keyBuffer), + xmlSecBufferGetSize(&ctx->keyBuffer)); + + /* perform the actual import */ + status = BCryptImportKey(hAlg, + NULL, + BCRYPT_KEY_DATA_BLOB, + &hKey, + pbKeyObject, + cbKeyObject, + xmlSecBufferGetData(&blob), + xmlSecBufferGetSize(&blob), + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptImportKey", NULL, status); + goto done; + } + + /* handle padding ourselves */ + if(out != in) { + memcpy(out, in, inSize); + } + + cbData = inSize; + status = BCryptDecrypt(hKey, + (PUCHAR)in, + inSize, + NULL, + NULL, + 0, + out, + inSize, + &cbData, + 0); + if(status != STATUS_SUCCESS) { + xmlSecMSCngNtError("BCryptDecrypt", NULL, status); + goto done; + } + + res = cbData; + +done: + if (hKey != NULL) { + BCryptDestroyKey(hKey); + } + + xmlSecBufferFinalize(&blob); + + if (pbKeyObject != NULL) { + xmlFree(pbKeyObject); + } + + if(hAlg != NULL) { + BCryptCloseAlgorithmProvider(hAlg, 0); + } + + return(res); +} + +/* klass for KW AES operation */ +static xmlSecKWAesKlass xmlSecMSCngKWAesKlass = { + /* callbacks */ + xmlSecMSCngKWAesBlockEncrypt, /* xmlSecKWAesBlockEncryptMethod encrypt; */ + xmlSecMSCngKWAesBlockDecrypt, /* xmlSecKWAesBlockDecryptMethod decrypt; */ + + /* for the future */ + NULL, /* void* reserved0; */ + NULL /* void* reserved1; */ +}; + +static int +xmlSecMSCngKWAesCheckId(xmlSecTransformPtr transform) { + + if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformKWAes128Id)) { + return(1); + } + + if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformKWAes192Id)) { + return(1); + } + + if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformKWAes256Id)) { + return(1); + } + + return(0); +} + +static int +xmlSecMSCngKWAesInitialize(xmlSecTransformPtr transform) { + xmlSecMSCngKWAesCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecMSCngKWAesCheckId(transform), -1); + xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngKWAesSize), -1); + + ctx = xmlSecMSCngKWAesGetCtx(transform); + xmlSecAssert2(ctx != NULL, -1); + + memset(ctx, 0, sizeof(xmlSecMSCngKWAesCtx)); + + ctx->pszAlgId = BCRYPT_AES_ALGORITHM; + ctx->keyId = xmlSecMSCngKeyDataAesId; + + if(transform->id == xmlSecMSCngTransformKWAes128Id) { + ctx->keySize = XMLSEC_KW_AES128_KEY_SIZE; + } else if(transform->id == xmlSecMSCngTransformKWAes192Id) { + ctx->keySize = XMLSEC_KW_AES192_KEY_SIZE; + } else if(transform->id == xmlSecMSCngTransformKWAes256Id) { + ctx->keySize = XMLSEC_KW_AES256_KEY_SIZE; + } else { + xmlSecInvalidTransfromError(transform) + return(-1); + } + + ret = xmlSecBufferInitialize(&ctx->keyBuffer, 0); + if(ret < 0) { + xmlSecInternalError("xmlSecBufferInitialize", + xmlSecTransformGetName(transform)); + return(-1); + } + + return(0); +} + +static void +xmlSecMSCngKWAesFinalize(xmlSecTransformPtr transform) { + xmlSecMSCngKWAesCtxPtr ctx; + + xmlSecAssert(xmlSecMSCngKWAesCheckId(transform)); + xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecMSCngKWAesSize)); + + ctx = xmlSecMSCngKWAesGetCtx(transform); + xmlSecAssert(ctx != NULL); + + xmlSecBufferFinalize(&ctx->keyBuffer); + + memset(ctx, 0, sizeof(xmlSecMSCngKWAesCtx)); +} + +static int +xmlSecMSCngKWAesSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) { + xmlSecMSCngKWAesCtxPtr ctx; + + xmlSecAssert2(xmlSecMSCngKWAesCheckId(transform), -1); + xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || + (transform->operation == xmlSecTransformOperationDecrypt), -1); + xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngKWAesSize), -1); + xmlSecAssert2(keyReq != NULL, -1); + + ctx = xmlSecMSCngKWAesGetCtx(transform); + xmlSecAssert2(ctx != NULL, -1); + + keyReq->keyId = ctx->keyId; + keyReq->keyType = xmlSecKeyDataTypeSymmetric; + if(transform->operation == xmlSecTransformOperationEncrypt) { + keyReq->keyUsage = xmlSecKeyUsageEncrypt; + } else { + keyReq->keyUsage = xmlSecKeyUsageDecrypt; + } + keyReq->keyBitsSize = ctx->keySize * 8; + return(0); +} + +static int +xmlSecMSCngKWAesSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { + xmlSecMSCngKWAesCtxPtr ctx; + xmlSecBufferPtr buffer; + xmlSecSize keySize; + int ret; + + xmlSecAssert2(xmlSecMSCngKWAesCheckId(transform), -1); + xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || + (transform->operation == xmlSecTransformOperationDecrypt), -1); + xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngKWAesSize), -1); + xmlSecAssert2(key != NULL, -1); + xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), + xmlSecMSCngKeyDataAesId), -1); + + ctx = xmlSecMSCngKWAesGetCtx(transform); + xmlSecAssert2(ctx != NULL, -1); + + buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key)); + xmlSecAssert2(buffer != NULL, -1); + + keySize = xmlSecBufferGetSize(buffer); + if(keySize < ctx->keySize) { + xmlSecInvalidKeyDataSizeError(keySize, ctx->keySize, + xmlSecTransformGetName(transform)); + return(-1); + } + + ret = xmlSecBufferSetData(&ctx->keyBuffer, xmlSecBufferGetData(buffer), + ctx->keySize); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferSetData", + xmlSecTransformGetName(transform), "size=%d", ctx->keySize); + return(-1); + } + + return(0); +} + +static int +xmlSecMSCngKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { + xmlSecMSCngKWAesCtxPtr ctx; + xmlSecBufferPtr in, out; + xmlSecSize inSize, outSize; + int ret; + + xmlSecAssert2(xmlSecMSCngKWAesCheckId(transform), -1); + xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || + (transform->operation == xmlSecTransformOperationDecrypt), -1); + xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngKWAesSize), -1); + xmlSecAssert2(transformCtx != NULL, -1); + + ctx = xmlSecMSCngKWAesGetCtx(transform); + xmlSecAssert2(ctx != NULL, -1); + + in = &transform->inBuf; + out = &transform->outBuf; + inSize = xmlSecBufferGetSize(in); + outSize = xmlSecBufferGetSize(out); + xmlSecAssert2(outSize == 0, -1); + + if(transform->status == xmlSecTransformStatusNone) { + transform->status = xmlSecTransformStatusWorking; + } + + if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { + /* just do nothing */ + } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { + if((inSize % 8) != 0) { + xmlSecInvalidSizeNotMultipleOfError("transform->inBuf", inSize, 8, + xmlSecTransformGetName(transform)); + return(-1); + } + + if(transform->operation == xmlSecTransformOperationEncrypt) { + /* the encoded key might be 8 bytes longer plus 8 bytes just in + * case */ + outSize = inSize + XMLSEC_KW_AES_MAGIC_BLOCK_SIZE + + XMLSEC_KW_AES_BLOCK_SIZE; + } else { + outSize = inSize + XMLSEC_KW_AES_BLOCK_SIZE; + } + + ret = xmlSecBufferSetMaxSize(out, outSize); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferSetMaxSize", + xmlSecTransformGetName(transform), "size=%d", outSize); + return(-1); + } + + if(transform->operation == xmlSecTransformOperationEncrypt) { + ret = xmlSecKWAesEncode(&xmlSecMSCngKWAesKlass, ctx, + xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), + outSize); + if(ret < 0) { + xmlSecInternalError("xmlSecKWAesEncode", + xmlSecTransformGetName(transform)); + return(-1); + } + + outSize = ret; + } else { + ret = xmlSecKWAesDecode(&xmlSecMSCngKWAesKlass, ctx, + xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), + outSize); + if(ret < 0) { + xmlSecInternalError("xmlSecKWAesEncode", + xmlSecTransformGetName(transform)); + return(-1); + } + outSize = ret; + } + + ret = xmlSecBufferSetSize(out, outSize); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferSetSize", + xmlSecTransformGetName(transform), "size=%d", outSize); + return(-1); + } + + ret = xmlSecBufferRemoveHead(in, inSize); + if(ret < 0) { + xmlSecInternalError2("xmlSecBufferRemoveHead", + xmlSecTransformGetName(transform), "size=%d", inSize); + return(-1); + } + + transform->status = xmlSecTransformStatusFinished; + } else if(transform->status == xmlSecTransformStatusFinished) { + /* the only way we can get here is if there is no input */ + xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); + } else { + xmlSecInvalidTransfromStatusError(transform); + return(-1); + } + + return(0); +} + +/* + * The AES-128 key wrapper transform klass. + */ +static xmlSecTransformKlass xmlSecMSCngKWAes128Klass = { + /* klass/object sizes */ + sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ + xmlSecMSCngKWAesSize, /* xmlSecSize objSize */ + + xmlSecNameKWAes128, /* const xmlChar* name; */ + xmlSecHrefKWAes128, /* const xmlChar* href; */ + xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ + + xmlSecMSCngKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */ + xmlSecMSCngKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */ + NULL, /* xmlSecTransformNodeReadMethod readNode; */ + NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ + xmlSecMSCngKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ + xmlSecMSCngKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */ + NULL, /* xmlSecTransformValidateMethod validate; */ + xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ + xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ + xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ + NULL, /* xmlSecTransformPushXmlMethod pushXml; */ + NULL, /* xmlSecTransformPopXmlMethod popXml; */ + xmlSecMSCngKWAesExecute, /* xmlSecTransformExecuteMethod execute; */ + + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecMSCngTransformKWAes128GetKlass: + * + * The AES-128 key wrapper transform klass. + * + * Returns: AES-128 key wrapper transform klass. + */ +xmlSecTransformId +xmlSecMSCngTransformKWAes128GetKlass(void) { + return(&xmlSecMSCngKWAes128Klass); +} + +/* + * The AES-192 key wrapper transform klass. + */ +static xmlSecTransformKlass xmlSecMSCngKWAes192Klass = { + /* klass/object sizes */ + sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ + xmlSecMSCngKWAesSize, /* xmlSecSize objSize */ + + xmlSecNameKWAes192, /* const xmlChar* name; */ + xmlSecHrefKWAes192, /* const xmlChar* href; */ + xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ + + xmlSecMSCngKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */ + xmlSecMSCngKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */ + NULL, /* xmlSecTransformNodeReadMethod readNode; */ + NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ + xmlSecMSCngKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ + xmlSecMSCngKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */ + NULL, /* xmlSecTransformValidateMethod validate; */ + xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ + xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ + xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ + NULL, /* xmlSecTransformPushXmlMethod pushXml; */ + NULL, /* xmlSecTransformPopXmlMethod popXml; */ + xmlSecMSCngKWAesExecute, /* xmlSecTransformExecuteMethod execute; */ + + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecMSCngTransformKWAes192GetKlass: + * + * The AES-192 key wrapper transform klass. + * + * Returns: AES-192 key wrapper transform klass. + */ +xmlSecTransformId +xmlSecMSCngTransformKWAes192GetKlass(void) { + return(&xmlSecMSCngKWAes192Klass); +} + +/* + * The AES-256 key wrapper transform klass. + */ +static xmlSecTransformKlass xmlSecMSCngKWAes256Klass = { + /* klass/object sizes */ + sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ + xmlSecMSCngKWAesSize, /* xmlSecSize objSize */ + + xmlSecNameKWAes256, /* const xmlChar* name; */ + xmlSecHrefKWAes256, /* const xmlChar* href; */ + xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ + + xmlSecMSCngKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */ + xmlSecMSCngKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */ + NULL, /* xmlSecTransformNodeReadMethod readNode; */ + NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ + xmlSecMSCngKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ + xmlSecMSCngKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */ + NULL, /* xmlSecTransformValidateMethod validate; */ + xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ + xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ + xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ + NULL, /* xmlSecTransformPushXmlMethod pushXml; */ + NULL, /* xmlSecTransformPopXmlMethod popXml; */ + xmlSecMSCngKWAesExecute, /* xmlSecTransformExecuteMethod execute; */ + + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecMSCngTransformKWAes256GetKlass: + * + * The AES-256 key wrapper transform klass. + * + * Returns: AES-256 key wrapper transform klass. + */ +xmlSecTransformId +xmlSecMSCngTransformKWAes256GetKlass(void) { + return(&xmlSecMSCngKWAes256Klass); +} + +#endif /* XMLSEC_NO_AES */ |