summaryrefslogtreecommitdiff
path: root/src/openssl/kw_aes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openssl/kw_aes.c')
-rw-r--r--src/openssl/kw_aes.c875
1 files changed, 383 insertions, 492 deletions
diff --git a/src/openssl/kw_aes.c b/src/openssl/kw_aes.c
index 94cfeddb..573fb985 100644
--- a/src/openssl/kw_aes.c
+++ b/src/openssl/kw_aes.c
@@ -1,12 +1,12 @@
-/**
+/**
*
* XMLSec library
- *
+ *
* AES Algorithm support
- *
+ *
* This is free software; see Copyright file in the source
* distribution for preciese wording.
- *
+ *
* Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
*/
#ifndef XMLSEC_NO_AES
@@ -28,269 +28,193 @@
#include <xmlsec/openssl/crypto.h>
-#define XMLSEC_OPENSSL_AES128_KEY_SIZE 16
-#define XMLSEC_OPENSSL_AES192_KEY_SIZE 24
-#define XMLSEC_OPENSSL_AES256_KEY_SIZE 32
-#define XMLSEC_OPENSSL_AES_IV_SIZE 16
-#define XMLSEC_OPENSSL_AES_BLOCK_SIZE 16
+#include "../kw_aes_des.h"
/*********************************************************************
*
- * AES KW transforms
- *
- * key (xmlSecBuffer) is located after xmlSecTransform structure
+ * AES KW implementation
*
- ********************************************************************/
-#define xmlSecOpenSSLKWAesGetKey(transform) \
- ((xmlSecBufferPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
-#define xmlSecOpenSSLKWAesSize \
- (sizeof(xmlSecTransform) + sizeof(xmlSecBuffer))
-
-static int xmlSecOpenSSLKWAesInitialize (xmlSecTransformPtr transform);
-static void xmlSecOpenSSLKWAesFinalize (xmlSecTransformPtr transform);
-static int xmlSecOpenSSLKWAesSetKeyReq (xmlSecTransformPtr transform,
- xmlSecKeyReqPtr keyReq);
-static int xmlSecOpenSSLKWAesSetKey (xmlSecTransformPtr transform,
- xmlSecKeyPtr key);
-static int xmlSecOpenSSLKWAesExecute (xmlSecTransformPtr transform,
- int last,
- xmlSecTransformCtxPtr transformCtx);
-static xmlSecSize xmlSecOpenSSLKWAesGetKeySize (xmlSecTransformPtr transform);
-static int xmlSecOpenSSLKWAesEncode (const xmlSecByte *key,
- xmlSecSize keySize,
- const xmlSecByte* in,
- xmlSecSize inSize,
- xmlSecByte* out,
- xmlSecSize outSize);
-static int xmlSecOpenSSLKWAesDecode (const xmlSecByte *key,
- xmlSecSize keySize,
- const xmlSecByte* in,
- xmlSecSize inSize,
- xmlSecByte* out,
- xmlSecSize outSize);
-
-static xmlSecTransformKlass xmlSecOpenSSLKWAes128Klass = {
- /* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
-
- xmlSecNameKWAes128, /* const xmlChar* name; */
- xmlSecHrefKWAes128, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ *********************************************************************/
+static int xmlSecOpenSSLKWAesBlockEncrypt (const xmlSecByte * in,
+ xmlSecSize inSize,
+ xmlSecByte * out,
+ xmlSecSize outSize,
+ void * context);
+static int xmlSecOpenSSLKWAesBlockDecrypt (const xmlSecByte * in,
+ xmlSecSize inSize,
+ xmlSecByte * out,
+ xmlSecSize outSize,
+ void * context);
+static xmlSecKWAesKlass xmlSecOpenSSLKWAesKlass = {
+ /* callbacks */
+ xmlSecOpenSSLKWAesBlockEncrypt, /* xmlSecKWAesBlockEncryptMethod encrypt; */
+ xmlSecOpenSSLKWAesBlockDecrypt, /* xmlSecKWAesBlockDecryptMethod decrypt; */
+
+ /* for the future */
+ NULL, /* void* reserved0; */
+ NULL /* void* reserved1; */
};
-static xmlSecTransformKlass xmlSecOpenSSLKWAes192Klass = {
- /* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
-
- xmlSecNameKWAes192, /* const xmlChar* name; */
- xmlSecHrefKWAes192, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
-};
-static xmlSecTransformKlass xmlSecOpenSSLKWAes256Klass = {
- /* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
-
- xmlSecNameKWAes256, /* const xmlChar* name; */
- xmlSecHrefKWAes256, /* const xmlChar* href; */
- xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- NULL, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
- xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+/*********************************************************************
+ *
+ * AES KW transforms
+ *
+ ********************************************************************/
+typedef struct _xmlSecOpenSSLKWAesCtx xmlSecOpenSSLKWAesCtx,
+ *xmlSecOpenSSLKWAesCtxPtr;
+struct _xmlSecOpenSSLKWAesCtx {
+ xmlSecBuffer keyBuffer;
+ xmlSecSize keyExpectedSize;
};
-
-#define XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE 8
-
+#define xmlSecOpenSSLKWAesSize \
+ (sizeof(xmlSecTransform) + sizeof(xmlSecOpenSSLKWAesCtx))
+#define xmlSecOpenSSLKWAesGetCtx(transform) \
+ ((xmlSecOpenSSLKWAesCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
#define xmlSecOpenSSLKWAesCheckId(transform) \
(xmlSecTransformCheckId((transform), xmlSecOpenSSLTransformKWAes128Id) || \
xmlSecTransformCheckId((transform), xmlSecOpenSSLTransformKWAes192Id) || \
xmlSecTransformCheckId((transform), xmlSecOpenSSLTransformKWAes256Id))
-/**
- * xmlSecOpenSSLTransformKWAes128GetKlass:
- *
- * The AES-128 kew wrapper transform klass.
- *
- * Returns: AES-128 kew wrapper transform klass.
- */
-xmlSecTransformId
-xmlSecOpenSSLTransformKWAes128GetKlass(void) {
- return(&xmlSecOpenSSLKWAes128Klass);
-}
-
-/**
- * xmlSecOpenSSLTransformKWAes192GetKlass:
- *
- * The AES-192 kew wrapper transform klass.
- *
- * Returns: AES-192 kew wrapper transform klass.
- */
-xmlSecTransformId
-xmlSecOpenSSLTransformKWAes192GetKlass(void) {
- return(&xmlSecOpenSSLKWAes192Klass);
-}
-
-/**
- * xmlSecOpenSSLTransformKWAes256GetKlass:
- *
- * The AES-256 kew wrapper transform klass.
- *
- * Returns: AES-256 kew wrapper transform klass.
- */
-xmlSecTransformId
-xmlSecOpenSSLTransformKWAes256GetKlass(void) {
- return(&xmlSecOpenSSLKWAes256Klass);
-}
-
-static int
+static int xmlSecOpenSSLKWAesInitialize (xmlSecTransformPtr transform);
+static void xmlSecOpenSSLKWAesFinalize (xmlSecTransformPtr transform);
+static int xmlSecOpenSSLKWAesSetKeyReq (xmlSecTransformPtr transform,
+ xmlSecKeyReqPtr keyReq);
+static int xmlSecOpenSSLKWAesSetKey (xmlSecTransformPtr transform,
+ xmlSecKeyPtr key);
+static int xmlSecOpenSSLKWAesExecute (xmlSecTransformPtr transform,
+ int last,
+ xmlSecTransformCtxPtr transformCtx);
+
+static int
xmlSecOpenSSLKWAesInitialize(xmlSecTransformPtr transform) {
+ xmlSecOpenSSLKWAesCtxPtr ctx;
int ret;
-
+
xmlSecAssert2(xmlSecOpenSSLKWAesCheckId(transform), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWAesSize), -1);
-
- ret = xmlSecBufferInitialize(xmlSecOpenSSLKWAesGetKey(transform), 0);
+
+ ctx = xmlSecOpenSSLKWAesGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes128Id)) {
+ ctx->keyExpectedSize = XMLSEC_KW_AES128_KEY_SIZE;
+ } else if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes192Id)) {
+ ctx->keyExpectedSize = XMLSEC_KW_AES192_KEY_SIZE;
+ } else if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes256Id)) {
+ ctx->keyExpectedSize = XMLSEC_KW_AES256_KEY_SIZE;
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_TRANSFORM,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecBufferInitialize(&(ctx->keyBuffer), 0);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecOpenSSLKWAesGetKey",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecOpenSSLKWAesGetKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
-
+
return(0);
}
-static void
+static void
xmlSecOpenSSLKWAesFinalize(xmlSecTransformPtr transform) {
+ xmlSecOpenSSLKWAesCtxPtr ctx;
+
xmlSecAssert(xmlSecOpenSSLKWAesCheckId(transform));
xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWAesSize));
-
- if(xmlSecOpenSSLKWAesGetKey(transform) != NULL) {
- xmlSecBufferFinalize(xmlSecOpenSSLKWAesGetKey(transform));
- }
+
+ ctx = xmlSecOpenSSLKWAesGetCtx(transform);
+ xmlSecAssert(ctx != NULL);
+
+ xmlSecBufferFinalize(&(ctx->keyBuffer));
}
-static int
+static int
xmlSecOpenSSLKWAesSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
+ xmlSecOpenSSLKWAesCtxPtr ctx;
+
xmlSecAssert2(xmlSecOpenSSLKWAesCheckId(transform), -1);
xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWAesSize), -1);
xmlSecAssert2(keyReq != NULL, -1);
- keyReq->keyId = xmlSecOpenSSLKeyDataAesId;
+ ctx = xmlSecOpenSSLKWAesGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ keyReq->keyId = xmlSecOpenSSLKeyDataAesId;
keyReq->keyType = xmlSecKeyDataTypeSymmetric;
if(transform->operation == xmlSecTransformOperationEncrypt) {
- keyReq->keyUsage = xmlSecKeyUsageEncrypt;
+ keyReq->keyUsage = xmlSecKeyUsageEncrypt;
} else {
- keyReq->keyUsage = xmlSecKeyUsageDecrypt;
+ keyReq->keyUsage = xmlSecKeyUsageDecrypt;
}
- keyReq->keyBitsSize = 8 * xmlSecOpenSSLKWAesGetKeySize(transform);
-
+ keyReq->keyBitsSize = 8 * ctx->keyExpectedSize;
+
return(0);
}
-static int
+static int
xmlSecOpenSSLKWAesSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
+ xmlSecOpenSSLKWAesCtxPtr ctx;
xmlSecBufferPtr buffer;
xmlSecSize keySize;
- xmlSecSize expectedKeySize;
int ret;
-
+
xmlSecAssert2(xmlSecOpenSSLKWAesCheckId(transform), -1);
xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWAesSize), -1);
- xmlSecAssert2(xmlSecOpenSSLKWAesGetKey(transform) != NULL, -1);
xmlSecAssert2(key != NULL, -1);
xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataAesId), -1);
-
+
+ ctx = xmlSecOpenSSLKWAesGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
xmlSecAssert2(buffer != NULL, -1);
keySize = xmlSecBufferGetSize(buffer);
- expectedKeySize = xmlSecOpenSSLKWAesGetKeySize(transform);
- if(keySize < expectedKeySize) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
- "key=%d;expected=%d",
- keySize, expectedKeySize);
- return(-1);
+ if(keySize < ctx->keyExpectedSize) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
+ "key=%d;expected=%d",
+ keySize, ctx->keyExpectedSize);
+ return(-1);
}
-
- ret = xmlSecBufferSetData(xmlSecOpenSSLKWAesGetKey(transform),
- xmlSecBufferGetData(buffer),
- expectedKeySize);
+
+ ret = xmlSecBufferSetData(&(ctx->keyBuffer),
+ xmlSecBufferGetData(buffer),
+ ctx->keyExpectedSize);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferSetData",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "expected-size=%d", expectedKeySize);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferSetData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "expected-size=%d",
+ ctx->keyExpectedSize);
+ return(-1);
}
return(0);
}
-static int
+static int
xmlSecOpenSSLKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
- xmlSecBufferPtr in, out, key;
- xmlSecSize inSize, outSize, keySize, expectedKeySize;
+ xmlSecOpenSSLKWAesCtxPtr ctx;
+ xmlSecBufferPtr in, out;
+ xmlSecSize inSize, outSize, keySize;
+ AES_KEY aesKey;
int ret;
xmlSecAssert2(xmlSecOpenSSLKWAesCheckId(transform), -1);
@@ -298,325 +222,292 @@ xmlSecOpenSSLKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransfor
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWAesSize), -1);
xmlSecAssert2(transformCtx != NULL, -1);
- key = xmlSecOpenSSLKWAesGetKey(transform);
- xmlSecAssert2(key != NULL, -1);
+ ctx = xmlSecOpenSSLKWAesGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ keySize = xmlSecBufferGetSize(&(ctx->keyBuffer));
+ xmlSecAssert2(keySize == ctx->keyExpectedSize, -1);
- keySize = xmlSecBufferGetSize(key);
- expectedKeySize = xmlSecOpenSSLKWAesGetKeySize(transform);
- xmlSecAssert2(keySize == expectedKeySize, -1);
-
in = &(transform->inBuf);
out = &(transform->outBuf);
inSize = xmlSecBufferGetSize(in);
- outSize = xmlSecBufferGetSize(out);
+ outSize = xmlSecBufferGetSize(out);
xmlSecAssert2(outSize == 0, -1);
-
+
if(transform->status == xmlSecTransformStatusNone) {
- transform->status = xmlSecTransformStatusWorking;
+ transform->status = xmlSecTransformStatusWorking;
}
-
+
if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) {
- /* just do nothing */
+ /* just do nothing */
} else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
- if((inSize % 8) != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_SIZE,
- "size=%d(not 8 bytes aligned)", inSize);
- return(-1);
- }
-
- if(transform->operation == xmlSecTransformOperationEncrypt) {
- /* the encoded key might be 8 bytes longer plus 8 bytes just in case */
- outSize = inSize + XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE +
- XMLSEC_OPENSSL_AES_BLOCK_SIZE;
- } else {
- outSize = inSize + XMLSEC_OPENSSL_AES_BLOCK_SIZE;
- }
-
- ret = xmlSecBufferSetMaxSize(out, outSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferSetMaxSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "outSize=%d", outSize);
- return(-1);
- }
-
- if(transform->operation == xmlSecTransformOperationEncrypt) {
- ret = xmlSecOpenSSLKWAesEncode(xmlSecBufferGetData(key), keySize,
- xmlSecBufferGetData(in), inSize,
- xmlSecBufferGetData(out), outSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecOpenSSLKWAesEncode",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- outSize = ret;
- } else {
- ret = xmlSecOpenSSLKWAesDecode(xmlSecBufferGetData(key), keySize,
- xmlSecBufferGetData(in), inSize,
- xmlSecBufferGetData(out), outSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecOpenSSLKWAesDecode",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
- outSize = ret;
- }
-
- ret = xmlSecBufferSetSize(out, outSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferSetSize",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "outSize=%d", outSize);
- return(-1);
- }
-
- ret = xmlSecBufferRemoveHead(in, inSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "inSize%d", inSize);
- return(-1);
- }
-
- transform->status = xmlSecTransformStatusFinished;
+ if((inSize % 8) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_SIZE,
+ "size=%d(not 8 bytes aligned)", inSize);
+ 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) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferSetMaxSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "outSize=%d", outSize);
+ return(-1);
+ }
+
+ if(transform->operation == xmlSecTransformOperationEncrypt) {
+ /* prepare key */
+ ret = AES_set_encrypt_key(xmlSecBufferGetData(&(ctx->keyBuffer)),
+ 8 * keySize,
+ &aesKey);
+ if(ret != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "AES_set_decrypt_key",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecKWAesEncode(&xmlSecOpenSSLKWAesKlass, &aesKey,
+ xmlSecBufferGetData(in), inSize,
+ xmlSecBufferGetData(out), outSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecKWAesEncode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ outSize = ret;
+ } else {
+ /* prepare key */
+ ret = AES_set_decrypt_key(xmlSecBufferGetData(&(ctx->keyBuffer)),
+ 8 * keySize,
+ &aesKey);
+ if(ret != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "AES_set_decrypt_key",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecKWAesDecode(&xmlSecOpenSSLKWAesKlass, &aesKey,
+ xmlSecBufferGetData(in), inSize,
+ xmlSecBufferGetData(out), outSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecKWAesEncode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ outSize = ret;
+ }
+
+ ret = xmlSecBufferSetSize(out, outSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "outSize=%d", outSize);
+ return(-1);
+ }
+
+ ret = xmlSecBufferRemoveHead(in, inSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "inSize%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);
+ /* the only way we can get here is if there is no input */
+ xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
} else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
}
return(0);
}
-static xmlSecSize
-xmlSecOpenSSLKWAesGetKeySize(xmlSecTransformPtr transform) {
- if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes128Id)) {
- return(XMLSEC_OPENSSL_AES128_KEY_SIZE);
- } else if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes192Id)) {
- return(XMLSEC_OPENSSL_AES192_KEY_SIZE);
- } else if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWAes256Id)) {
- return(XMLSEC_OPENSSL_AES256_KEY_SIZE);
- }
- return(0);
-}
+static xmlSecTransformKlass xmlSecOpenSSLKWAes128Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes128, /* const xmlChar* name; */
+ xmlSecHrefKWAes128, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
/**
- * http://www.w3.org/TR/xmlenc-core/#sec-Alg-SymmetricKeyWrap:
- *
- * Assume that the data to be wrapped consists of N 64-bit data blocks
- * denoted P(1), P(2), P(3) ... P(N). The result of wrapping will be N+1
- * 64-bit blocks denoted C(0), C(1), C(2), ... C(N). The key encrypting
- * key is represented by K. Assume integers i, j, and t and intermediate
- * 64-bit register A, 128-bit register B, and array of 64-bit quantities
- * R(1) through R(N).
+ * xmlSecOpenSSLTransformKWAes128GetKlass:
*
- * "|" represents concatentation so x|y, where x and y and 64-bit quantities,
- * is the 128-bit quantity with x in the most significant bits and y in the
- * least significant bits. AES(K)enc(x) is the operation of AES encrypting
- * the 128-bit quantity x under the key K. AES(K)dec(x) is the corresponding
- * decryption opteration. XOR(x,y) is the bitwise exclusive or of x and y.
- * MSB(x) and LSB(y) are the most significant 64 bits and least significant
- * 64 bits of x and y respectively.
+ * The AES-128 kew wrapper transform klass.
*
- * If N is 1, a single AES operation is performed for wrap or unwrap.
- * If N>1, then 6*N AES operations are performed for wrap or unwrap.
+ * Returns: AES-128 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecOpenSSLTransformKWAes128GetKlass(void) {
+ return(&xmlSecOpenSSLKWAes128Klass);
+}
+
+static xmlSecTransformKlass xmlSecOpenSSLKWAes192Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes192, /* const xmlChar* name; */
+ xmlSecHrefKWAes192, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+
+/**
+ * xmlSecOpenSSLTransformKWAes192GetKlass:
*
- * The key wrap algorithm is as follows:
+ * The AES-192 kew wrapper transform klass.
*
- * 1. If N is 1:
- * * B=AES(K)enc(0xA6A6A6A6A6A6A6A6|P(1))
- * * C(0)=MSB(B)
- * * C(1)=LSB(B)
- * If N>1, perform the following steps:
- * 2. Initialize variables:
- * * Set A to 0xA6A6A6A6A6A6A6A6
- * * Fori=1 to N,
- * R(i)=P(i)
- * 3. Calculate intermediate values:
- * * Forj=0 to 5,
- * o For i=1 to N,
- * t= i + j*N
- * B=AES(K)enc(A|R(i))
- * A=XOR(t,MSB(B))
- * R(i)=LSB(B)
- * 4. Output the results:
- * * Set C(0)=A
- * * For i=1 to N,
- * C(i)=R(i)
+ * Returns: AES-192 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecOpenSSLTransformKWAes192GetKlass(void) {
+ return(&xmlSecOpenSSLKWAes192Klass);
+}
+
+static xmlSecTransformKlass xmlSecOpenSSLKWAes256Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecOpenSSLKWAesSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes256, /* const xmlChar* name; */
+ xmlSecHrefKWAes256, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecOpenSSLKWAesInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecOpenSSLKWAesFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecOpenSSLKWAesSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecOpenSSLKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecOpenSSLKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecOpenSSLTransformKWAes256GetKlass:
*
- * The key unwrap algorithm is as follows:
+ * The AES-256 kew wrapper transform klass.
*
- * 1. If N is 1:
- * * B=AES(K)dec(C(0)|C(1))
- * * P(1)=LSB(B)
- * * If MSB(B) is 0xA6A6A6A6A6A6A6A6, return success. Otherwise,
- * return an integrity check failure error.
- * If N>1, perform the following steps:
- * 2. Initialize the variables:
- * * A=C(0)
- * * For i=1 to N,
- * R(i)=C(i)
- * 3. Calculate intermediate values:
- * * For j=5 to 0,
- * o For i=N to 1,
- * t= i + j*N
- * B=AES(K)dec(XOR(t,A)|R(i))
- * A=MSB(B)
- * R(i)=LSB(B)
- * 4. Output the results:
- * * For i=1 to N,
- * P(i)=R(i)
- * * If A is 0xA6A6A6A6A6A6A6A6, return success. Otherwise, return
- * an integrity check failure error.
+ * Returns: AES-256 kew wrapper transform klass.
*/
-static const xmlSecByte xmlSecOpenSSLKWAesMagicBlock[XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE] = {
- 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
-};
-
-static int
-xmlSecOpenSSLKWAesEncode(const xmlSecByte *key, xmlSecSize keySize,
- const xmlSecByte *in, xmlSecSize inSize,
- xmlSecByte *out, xmlSecSize outSize) {
- AES_KEY aesKey;
- xmlSecByte block[XMLSEC_OPENSSL_AES_BLOCK_SIZE];
- xmlSecByte *p;
- int N, i, j, t;
- int ret;
-
- xmlSecAssert2(key != NULL, -1);
- xmlSecAssert2(keySize > 0, -1);
+xmlSecTransformId
+xmlSecOpenSSLTransformKWAes256GetKlass(void) {
+ return(&xmlSecOpenSSLKWAes256Klass);
+}
+
+/*********************************************************************
+ *
+ * AES KW implementation
+ *
+ *********************************************************************/
+static int
+xmlSecOpenSSLKWAesBlockEncrypt(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * context) {
xmlSecAssert2(in != NULL, -1);
- xmlSecAssert2(inSize > 0, -1);
+ xmlSecAssert2(inSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(out != NULL, -1);
- xmlSecAssert2(outSize >= inSize + 8, -1);
-
- ret = AES_set_encrypt_key(key, 8 * keySize, &aesKey);
- if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "AES_set_encrypt_key",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ xmlSecAssert2(outSize >= AES_BLOCK_SIZE, -1);
+ xmlSecAssert2(context != NULL, -1);
- /* prepend magic block */
- if(in != out) {
- memcpy(out + XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE, in, inSize);
- } else {
- memmove(out + XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE, out, inSize);
- }
- memcpy(out, xmlSecOpenSSLKWAesMagicBlock, XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE);
-
- N = (inSize / 8);
- if(N == 1) {
- AES_encrypt(out, out, &aesKey);
- } else {
- for(j = 0; j <= 5; ++j) {
- for(i = 1; i <= N; ++i) {
- t = i + (j * N);
- p = out + i * 8;
-
- memcpy(block, out, 8);
- memcpy(block + 8, p, 8);
-
- AES_encrypt(block, block, &aesKey);
- block[7] ^= t;
- memcpy(out, block, 8);
- memcpy(p, block + 8, 8);
- }
- }
- }
-
- return(inSize + 8);
+ AES_encrypt(in, out, (AES_KEY*)context);
+ return(AES_BLOCK_SIZE);
}
-static int
-xmlSecOpenSSLKWAesDecode(const xmlSecByte *key, xmlSecSize keySize,
- const xmlSecByte *in, xmlSecSize inSize,
- xmlSecByte *out, xmlSecSize outSize) {
- AES_KEY aesKey;
- xmlSecByte block[XMLSEC_OPENSSL_AES_BLOCK_SIZE];
- xmlSecByte *p;
- int N, i, j, t;
- int ret;
-
- xmlSecAssert2(key != NULL, -1);
- xmlSecAssert2(keySize > 0, -1);
+static int
+xmlSecOpenSSLKWAesBlockDecrypt(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * context) {
xmlSecAssert2(in != NULL, -1);
- xmlSecAssert2(inSize > 0, -1);
+ xmlSecAssert2(inSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(out != NULL, -1);
- xmlSecAssert2(outSize >= inSize, -1);
-
- ret = AES_set_decrypt_key(key, 8 * keySize, &aesKey);
- if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "AES_set_decrypt_key",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
-
- /* copy input */
- if(in != out) {
- memcpy(out, in, inSize);
- }
-
- N = (inSize / 8) - 1;
- if(N == 1) {
- AES_decrypt(out, out, &aesKey);
- } else {
- for(j = 5; j >= 0; --j) {
- for(i = N; i > 0; --i) {
- t = i + (j * N);
- p = out + i * 8;
-
- memcpy(block, out, 8);
- memcpy(block + 8, p, 8);
- block[7] ^= t;
-
- AES_decrypt(block, block, &aesKey);
- memcpy(out, block, 8);
- memcpy(p, block + 8, 8);
- }
- }
- }
- /* do not left data in memory */
- memset(block, 0, sizeof(block));
-
- if(memcmp(xmlSecOpenSSLKWAesMagicBlock, out, XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE) != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_INVALID_DATA,
- "bad magic block");
- return(-1);
- }
-
- memmove(out, out + XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE, inSize - XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE);
- return(inSize - XMLSEC_OPENSSL_KW_AES_MAGIC_BLOCK_SIZE);
+ xmlSecAssert2(outSize >= AES_BLOCK_SIZE, -1);
+ xmlSecAssert2(context != NULL, -1);
+
+ AES_decrypt(in, out, (AES_KEY*)context);
+ return(AES_BLOCK_SIZE);
}
+
#endif /* XMLSEC_OPENSSL_096 */
#endif /* XMLSEC_NO_AES */