[xmlsec] adding AES KW support to xmlsec-mscrypto
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] adding AES KW support to xmlsec-mscrypto
- Date: Sat, 8 May 2010 08:16:19 +0000 (UTC)
commit 34e5d043269971f807c49faf2b679396aee992b0
Author: Aleksey Sanin <aleksey aleksey com>
Date: Sat May 8 01:12:13 2010 -0700
adding AES KW support to xmlsec-mscrypto
ChangeLog | 3 +
TODO | 23 +--
docs/xmlenc.html | 18 +-
include/xmlsec/mscrypto/crypto.h | 27 +++
src/kw_aes_des.c | 40 +++-
src/kw_aes_des.h | 16 +-
src/mscrypto/ciphers.c | 468 +++++++++++++++++++++++++++++++++++++-
src/mscrypto/crypto.c | 3 +
src/openssl/kw_aes.c | 30 ++-
tests/testEnc.sh | 6 +-
win32/mycfg.bat | 2 +-
11 files changed, 572 insertions(+), 64 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c2bdfec..483f5b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2010-05-08 Aleksey Sanin <aleksey aleksey com>
+ * Added AES KW support for xmlsec-mscrypto
+
2010-04-30 Aleksey Sanin <aleksey aleksey com>
* Added RSA/OAEP support for xmlsec-mscrypto
diff --git a/TODO b/TODO
index d4939bf..67dd7f3 100644
--- a/TODO
+++ b/TODO
@@ -47,11 +47,10 @@ merlin-xmldsig-twenty-three/signature-x509-crt-crl
-------------------------------------------------
-* xmlsec-mscrypto (April 26, 2010 using Windows XP SP3)
+* xmlsec-mscrypto (May 08, 2010 using Windows XP SP3)
-------------------------------------------------
-** Skipped tests due to missing transforms: RIPEMD160, SHA224,
-AES and DES KW
+** Skipped tests due to missing transforms: RIPEMD160, SHA224, DES KW
aleksey-xmldsig-01/enveloping-ripemd160-hmac-ripemd160
aleksey-xmldsig-01/enveloping-ripemd160-hmac-ripemd160-64
@@ -59,27 +58,11 @@ aleksey-xmldsig-01/enveloping-sha224-hmac-sha224
aleksey-xmldsig-01/enveloping-sha224-hmac-sha224-64
aleksey-xmldsig-01/enveloping-ripemd160-rsa-ripemd160
aleksey-xmldsig-01/enveloping-sha224-rsa-sha224
-
merlin-xmlenc-five/encsig-ripemd160-hmac-ripemd160-kw-tripledes
-merlin-xmlenc-five/encsig-sha256-hmac-sha256-kw-aes128
-merlin-xmlenc-five/encsig-sha384-hmac-sha384-kw-aes192
-merlin-xmlenc-five/encsig-sha512-hmac-sha512-kw-aes256
-aleksey-xmlenc-01/enc-des3cbc-aes192-keyname
merlin-xmlenc-five/encrypt-data-aes256-cbc-kw-tripledes
-merlin-xmlenc-five/encrypt-content-aes128-cbc-kw-aes192
-merlin-xmlenc-five/encrypt-data-aes192-cbc-kw-aes256
-merlin-xmlenc-five/encrypt-element-tripledes-cbc-kw-aes128
-merlin-xmlenc-five/encrypt-element-aes256-cbc-retrieved-kw-aes256
01-phaos-xmlenc-3/enc-element-3des-kw-3des
01-phaos-xmlenc-3/enc-content-aes128-kw-3des
-01-phaos-xmlenc-3/enc-element-aes128-kw-aes128
-01-phaos-xmlenc-3/enc-element-aes128-kw-aes256
-01-phaos-xmlenc-3/enc-content-3des-kw-aes192
-01-phaos-xmlenc-3/enc-content-aes192-kw-aes256
-01-phaos-xmlenc-3/enc-element-aes192-kw-aes192
-01-phaos-xmlenc-3/enc-element-aes256-kw-aes256
-01-phaos-xmlenc-3/enc-text-3des-kw-aes256
-01-phaos-xmlenc-3/enc-text-aes128-kw-aes192
+
** Failed tests due to no GOST crypto providers on test machine
diff --git a/docs/xmlenc.html b/docs/xmlenc.html
index 2d74b80..dc5739d 100644
--- a/docs/xmlenc.html
+++ b/docs/xmlenc.html
@@ -352,7 +352,7 @@ data. </li>
<td style="vertical-align: top;">Y</td>
</tr>
<tr>
-<td style="width: 40%;" valign="top"> AES-192<br>
+<td style="width: 40%;" valign="top">AES-192<br>
</td>
<td valign="top">Y<br>
</td>
@@ -405,7 +405,7 @@ Wrap<br>
<td style="vertical-align: top;">N</td>
</tr>
<tr>
-<td style="width: 40%;" valign="top"> AES-128 Key
+<td style="width: 40%;" valign="top">AES-128 Key
Wrap (128 bit keys)<br>
</td>
<td valign="top">Y<br>
@@ -413,30 +413,30 @@ Wrap (128 bit keys)<br>
<td style="vertical-align: top;">N</td>
<td style="vertical-align: top;">Y<br>
</td>
- <td style="vertical-align: top;">N<br>
+ <td style="vertical-align: top;">Y<br>
</td>
</tr>
<tr>
-<td style="width: 40%;" valign="top"> AES-256 Key
-Wrap (256 bit keys)<br>
+<td style="width: 40%;" valign="top"> AES-192 Key Wrap<br>
</td>
<td valign="top">Y<br>
</td>
<td style="vertical-align: top;">N</td>
<td style="vertical-align: top;">Y<br>
</td>
- <td style="vertical-align: top;">N<br>
-</td>
+ <td style="vertical-align: top;">Y</td>
</tr>
<tr>
-<td style="width: 40%;" valign="top"> AES-192 Key Wrap<br>
+<td style="width: 40%;" valign="top"> AES-256 Key
+Wrap (256 bit keys)<br>
</td>
<td valign="top">Y<br>
</td>
<td style="vertical-align: top;">N</td>
<td style="vertical-align: top;">Y<br>
</td>
- <td style="vertical-align: top;">N</td>
+ <td style="vertical-align: top;">Y<br>
+</td>
</tr>
<tr>
<td style="width: 40%;" valign="top"> SHA1<br>
diff --git a/include/xmlsec/mscrypto/crypto.h b/include/xmlsec/mscrypto/crypto.h
index ab3a026..ad24322 100644
--- a/include/xmlsec/mscrypto/crypto.h
+++ b/include/xmlsec/mscrypto/crypto.h
@@ -361,6 +361,33 @@ XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformAes192CbcGetKlass
xmlSecMSCryptoTransformAes256CbcGetKlass()
XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformAes256CbcGetKlass(void);
+/**
+ * xmlSecMSCryptoTransformKWAes128Id:
+ *
+ * The AES 128 key wrap transform klass.
+ */
+#define xmlSecMSCryptoTransformKWAes128Id \
+ xmlSecMSCryptoTransformKWAes128GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformKWAes128GetKlass(void);
+
+/**
+ * xmlSecMSCryptoTransformKWAes192Id:
+ *
+ * The AES 192 key wrap transform klass.
+ */
+#define xmlSecMSCryptoTransformKWAes192Id \
+ xmlSecMSCryptoTransformKWAes192GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformKWAes192GetKlass(void);
+
+/**
+ * xmlSecMSCryptoTransformKWAes256Id:
+ *
+ * The AES 256 key wrap transform klass.
+ */
+#define xmlSecMSCryptoTransformKWAes256Id \
+ xmlSecMSCryptoTransformKWAes256GetKlass()
+XMLSEC_CRYPTO_EXPORT xmlSecTransformId xmlSecMSCryptoTransformKWAes256GetKlass(void);
+
#endif /* XMLSEC_NO_AES */
diff --git a/src/kw_aes_des.c b/src/kw_aes_des.c
index ae6452e..638edd3 100644
--- a/src/kw_aes_des.c
+++ b/src/kw_aes_des.c
@@ -127,7 +127,15 @@ xmlSecKWAesEncode(xmlSecAesBlockEncryptCallback encryptCallback, void *key,
N = (inSize / 8);
if(N == 1) {
- encryptCallback(out, out, key);
+ ret = encryptCallback(out, inSize + XMLSEC_KW_AES_MAGIC_BLOCK_SIZE, out, outSize, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "encryptCallback",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
} else {
for(j = 0; j <= 5; ++j) {
for(i = 1; i <= N; ++i) {
@@ -137,7 +145,15 @@ xmlSecKWAesEncode(xmlSecAesBlockEncryptCallback encryptCallback, void *key,
memcpy(block, out, 8);
memcpy(block + 8, p, 8);
- encryptCallback(block, block, key);
+ ret = encryptCallback(block, sizeof(block), block, sizeof(block), key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "encryptCallback",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
block[7] ^= t;
memcpy(out, block, 8);
memcpy(p, block + 8, 8);
@@ -171,7 +187,15 @@ xmlSecKWAesDecode(xmlSecAesBlockDecryptCallback decryptCallback, void *key,
N = (inSize / 8) - 1;
if(N == 1) {
- decryptCallback(out, out, key);
+ ret = decryptCallback(out, inSize, out, outSize, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "decryptCallback",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
} else {
for(j = 5; j >= 0; --j) {
for(i = N; i > 0; --i) {
@@ -182,7 +206,15 @@ xmlSecKWAesDecode(xmlSecAesBlockDecryptCallback decryptCallback, void *key,
memcpy(block + 8, p, 8);
block[7] ^= t;
- decryptCallback(block, block, key);
+ ret = decryptCallback(block, sizeof(block), block, sizeof(block), key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "encryptCallback",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
memcpy(out, block, 8);
memcpy(p, block + 8, 8);
}
diff --git a/src/kw_aes_des.h b/src/kw_aes_des.h
index d6a7504..9283a18 100755
--- a/src/kw_aes_des.h
+++ b/src/kw_aes_des.h
@@ -34,12 +34,16 @@ extern "C" {
#define XMLSEC_KW_AES192_KEY_SIZE 24
#define XMLSEC_KW_AES256_KEY_SIZE 32
-typedef int (*xmlSecAesBlockEncryptCallback) (const xmlSecByte * in,
- xmlSecByte * out,
- void * key);
-typedef int (*xmlSecAesBlockDecryptCallback) (const xmlSecByte * in,
- xmlSecByte * out,
- void * key);
+typedef int (*xmlSecAesBlockEncryptCallback) (const xmlSecByte * in,
+ xmlSecSize inSize,
+ xmlSecByte * out,
+ xmlSecSize outSize,
+ void * key);
+typedef int (*xmlSecAesBlockDecryptCallback) (const xmlSecByte * in,
+ xmlSecSize inSize,
+ xmlSecByte * out,
+ xmlSecSize outSize,
+ void * key);
XMLSEC_EXPORT int
diff --git a/src/mscrypto/ciphers.c b/src/mscrypto/ciphers.c
index 3c70474..0aa0fe7 100644
--- a/src/mscrypto/ciphers.c
+++ b/src/mscrypto/ciphers.c
@@ -20,14 +20,16 @@
#include <xmlsec/errors.h>
#include <xmlsec/mscrypto/crypto.h>
+
+#include "../kw_aes_des.h"
#include "private.h"
+
#if defined(__MINGW32__)
# include "xmlsec-mingw.h"
#endif
-
/**************************************************************************
*
* Internal MSCrypto Block cipher CTX
@@ -37,15 +39,15 @@ typedef struct _xmlSecMSCryptoBlockCipherCtx xmlSecMSCryptoBlockCiphe
*xmlSecMSCryptoBlockCipherCtxPtr;
struct _xmlSecMSCryptoBlockCipherCtx {
ALG_ID algorithmIdentifier;
- int mode;
+ const xmlSecMSCryptoProviderInfo * providers;
+ xmlSecKeyDataId keyId;
+ xmlSecSize keySize;
+
HCRYPTPROV cryptProvider;
- HCRYPTKEY cryptKey;
HCRYPTKEY pubPrivKey;
- xmlSecKeyDataId keyId;
- const xmlSecMSCryptoProviderInfo * providers;
- int keyInitialized;
+ HCRYPTKEY cryptKey;
+ xmlSecBuffer kwKeyBuffer; /* used only for KW algorithm - need to reset cryptKey for every operation to avoid CBC mode */
int ctxInitialized;
- xmlSecSize keySize;
};
/* function declarations */
static int xmlSecMSCryptoBlockCipherCtxUpdate (xmlSecMSCryptoBlockCipherCtxPtr ctx,
@@ -68,7 +70,7 @@ xmlSecMSCryptoBlockCipherCtxInit(xmlSecMSCryptoBlockCipherCtxPtr ctx,
DWORD dwBlockLen, dwBlockLenLen;
xmlSecAssert2(ctx != NULL, -1);
- xmlSecAssert2(ctx->keyInitialized != 0, -1);
+ xmlSecAssert2(ctx->cryptKey != 0, -1);
xmlSecAssert2(ctx->ctxInitialized == 0, -1);
xmlSecAssert2(in != NULL, -1);
xmlSecAssert2(out != NULL, -1);
@@ -496,6 +498,13 @@ xmlSecMSCryptoBlockCipherCheckId(xmlSecTransformPtr transform) {
return(1);
}
+
+ if(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformKWAes128Id) ||
+ xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformKWAes192Id) ||
+ xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformKWAes256Id)) {
+
+ return(1);
+ }
#endif /* XMLSEC_NO_AES */
return(0);
@@ -504,6 +513,7 @@ xmlSecMSCryptoBlockCipherCheckId(xmlSecTransformPtr transform) {
static int
xmlSecMSCryptoBlockCipherInitialize(xmlSecTransformPtr transform) {
xmlSecMSCryptoBlockCipherCtxPtr ctx;
+ int ret;
xmlSecAssert2(xmlSecMSCryptoBlockCipherCheckId(transform), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoBlockCipherSize), -1);
@@ -513,6 +523,16 @@ xmlSecMSCryptoBlockCipherInitialize(xmlSecTransformPtr transform) {
memset(ctx, 0, sizeof(xmlSecMSCryptoBlockCipherCtx));
+ ret = xmlSecBufferInitialize(&ctx->kwKeyBuffer, 0);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
#ifndef XMLSEC_NO_DES
if(transform->id == xmlSecMSCryptoTransformDes3CbcId) {
ctx->algorithmIdentifier = CALG_3DES;
@@ -538,7 +558,23 @@ xmlSecMSCryptoBlockCipherInitialize(xmlSecTransformPtr transform) {
ctx->keyId = xmlSecMSCryptoKeyDataAesId;
ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
ctx->keySize = 32;
+ } else if(transform->id == xmlSecMSCryptoTransformKWAes128Id) {
+ ctx->algorithmIdentifier = CALG_AES_128;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = XMLSEC_KW_AES128_KEY_SIZE;
+ } else if(transform->id == xmlSecMSCryptoTransformKWAes192Id) {
+ ctx->algorithmIdentifier = CALG_AES_192;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = XMLSEC_KW_AES192_KEY_SIZE;
+ } else if(transform->id == xmlSecMSCryptoTransformKWAes256Id) {
+ ctx->algorithmIdentifier = CALG_AES_256;
+ ctx->keyId = xmlSecMSCryptoKeyDataAesId;
+ ctx->providers = xmlSecMSCryptoProviderInfo_Aes;
+ ctx->keySize = XMLSEC_KW_AES256_KEY_SIZE;
} else
+
#endif /* XMLSEC_NO_AES */
{
@@ -595,6 +631,8 @@ xmlSecMSCryptoBlockCipherFinalize(xmlSecTransformPtr transform) {
if (ctx->cryptProvider) {
CryptReleaseContext(ctx->cryptProvider, 0);
}
+
+ xmlSecBufferFinalize(&ctx->kwKeyBuffer);
memset(ctx, 0, sizeof(xmlSecMSCryptoBlockCipherCtx));
}
@@ -637,7 +675,7 @@ xmlSecMSCryptoBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key)
ctx = xmlSecMSCryptoBlockCipherGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
- xmlSecAssert2(ctx->keyInitialized == 0, -1);
+ xmlSecAssert2(ctx->cryptKey == 0, -1);
xmlSecAssert2(ctx->pubPrivKey != 0, -1);
xmlSecAssert2(ctx->keyId != NULL, -1);
xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
@@ -676,7 +714,6 @@ xmlSecMSCryptoBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key)
return(-1);
}
- ctx->keyInitialized = 1;
return(0);
}
@@ -941,3 +978,414 @@ xmlSecMSCryptoTransformDes3CbcGetKlass(void) {
}
#endif /* XMLSEC_NO_DES */
+#ifndef XMLSEC_NO_AES
+static int
+xmlSecMSCryptoAesBlockEncryptCallback(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * key) {
+ xmlSecMSCryptoBlockCipherCtxPtr ctx = (xmlSecMSCryptoBlockCipherCtxPtr)key;
+ DWORD dwCLen;
+
+ 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(ctx->pubPrivKey != 0, -1);
+ xmlSecAssert2(ctx->cryptKey == 0, -1);
+ xmlSecAssert2(xmlSecBufferGetSize(&ctx->kwKeyBuffer) == ctx->keySize, -1);
+
+ /* Import this key and get an HCRYPTKEY handle, we do it again and again
+ to ensure we don't go into CBC mode */
+ if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->cryptProvider,
+ ctx->pubPrivKey,
+ ctx->algorithmIdentifier,
+ xmlSecBufferGetData(&ctx->kwKeyBuffer),
+ xmlSecBufferGetSize(&ctx->kwKeyBuffer),
+ TRUE,
+ &(ctx->cryptKey))) {
+
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoImportPlainSessionBlob",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* Set process last block to false, since we handle padding ourselves, and MSCrypto padding
+ * can be skipped. I hope this will work .... */
+ memcpy(out, in, inSize);
+ dwCLen = inSize;
+ if(!CryptEncrypt(ctx->cryptKey, 0, FALSE, 0, out, &dwCLen, outSize)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "CryptEncrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* cleanup */
+ if (ctx->cryptKey != 0) {
+ CryptDestroyKey(ctx->cryptKey);
+ ctx->cryptKey = 0;
+ }
+
+ return(0);
+}
+
+static int
+xmlSecMSCryptoAesBlockDecryptCallback(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * key) {
+ xmlSecMSCryptoBlockCipherCtxPtr ctx = (xmlSecMSCryptoBlockCipherCtxPtr)key;
+ DWORD dwCLen;
+
+ 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(ctx->pubPrivKey != 0, -1);
+ xmlSecAssert2(ctx->cryptKey == 0, -1);
+ xmlSecAssert2(xmlSecBufferGetSize(&ctx->kwKeyBuffer) == ctx->keySize, -1);
+
+ /* Import this key and get an HCRYPTKEY handle, we do it again and again
+ to ensure we don't go into CBC mode */
+ if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->cryptProvider,
+ ctx->pubPrivKey,
+ ctx->algorithmIdentifier,
+ xmlSecBufferGetData(&ctx->kwKeyBuffer),
+ xmlSecBufferGetSize(&ctx->kwKeyBuffer),
+ TRUE,
+ &(ctx->cryptKey))) {
+
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoImportPlainSessionBlob",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* Set process last block to false, since we handle padding ourselves, and MSCrypto padding
+ * can be skipped. I hope this will work .... */
+ memcpy(out, in, inSize);
+ dwCLen = inSize;
+ if(!CryptDecrypt(ctx->cryptKey, 0, FALSE, 0, out, &dwCLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "CryptEncrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* cleanup */
+ if (ctx->cryptKey != 0) {
+ CryptDestroyKey(ctx->cryptKey);
+ ctx->cryptKey = 0;
+ }
+
+ return(0);
+}
+
+static int
+xmlSecMSCryptoKWAesSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
+ xmlSecMSCryptoBlockCipherCtxPtr ctx;
+ xmlSecBufferPtr buffer;
+ xmlSecSize keySize;
+ int ret;
+
+ xmlSecAssert2(xmlSecMSCryptoBlockCipherCheckId(transform), -1);
+ xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoBlockCipherSize), -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecMSCryptoKeyDataAesId), -1);
+
+ ctx = xmlSecMSCryptoBlockCipherGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
+ xmlSecAssert2(buffer != NULL, -1);
+
+ keySize = xmlSecBufferGetSize(buffer);
+ if(keySize < ctx->keySize) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
+ "key=%d;expected=%d",
+ keySize, ctx->keySize);
+ return(-1);
+ }
+
+ ret = xmlSecBufferSetData(&(ctx->kwKeyBuffer),
+ xmlSecBufferGetData(buffer),
+ ctx->keySize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferSetData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "expected-size=%d",
+ ctx->keySize);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecMSCryptoKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
+ xmlSecMSCryptoBlockCipherCtxPtr ctx;
+ xmlSecBufferPtr in, out;
+ xmlSecSize inSize, outSize;
+ int ret;
+
+ xmlSecAssert2(xmlSecMSCryptoBlockCipherCheckId(transform), -1);
+ xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
+ xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoBlockCipherSize), -1);
+ xmlSecAssert2(transformCtx != NULL, -1);
+
+ ctx = xmlSecMSCryptoBlockCipherGetCtx(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) {
+ 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) {
+ ret = xmlSecKWAesEncode(xmlSecMSCryptoAesBlockEncryptCallback, ctx,
+ 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 {
+ ret = xmlSecKWAesDecode(xmlSecMSCryptoAesBlockDecryptCallback, ctx,
+ 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);
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
+ }
+ return(0);
+}
+
+/*********************************************************************
+ *
+ * AES KW cipher transforms
+ *
+ ********************************************************************/
+
+/*
+ * The AES-128 kew wrapper transform klass.
+ */
+static xmlSecTransformKlass xmlSecMSCryptoKWAes128Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes128, /* const xmlChar* name; */
+ xmlSecHrefKWAes128, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformKWAes128GetKlass:
+ *
+ * The AES-128 kew wrapper transform klass.
+ *
+ * Returns: AES-128 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformKWAes128GetKlass(void) {
+ return(&xmlSecMSCryptoKWAes128Klass);
+}
+
+
+/*
+ * The AES-192 kew wrapper transform klass.
+ */
+static xmlSecTransformKlass xmlSecMSCryptoKWAes192Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes192, /* const xmlChar* name; */
+ xmlSecHrefKWAes192, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformKWAes192GetKlass:
+ *
+ * The AES-192 kew wrapper transform klass.
+ *
+ * Returns: AES-192 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformKWAes192GetKlass(void) {
+ return(&xmlSecMSCryptoKWAes192Klass);
+}
+
+/*
+ * The AES-256 kew wrapper transform klass.
+ */
+static xmlSecTransformKlass xmlSecMSCryptoKWAes256Klass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecMSCryptoBlockCipherSize, /* xmlSecSize objSize */
+
+ xmlSecNameKWAes256, /* const xmlChar* name; */
+ xmlSecHrefKWAes256, /* const xmlChar* href; */
+ xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecMSCryptoBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecMSCryptoBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ xmlSecMSCryptoBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
+ xmlSecMSCryptoKWAesSetKey, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecMSCryptoKWAesExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecMSCryptoTransformKWAes256GetKlass:
+ *
+ * The AES-256 kew wrapper transform klass.
+ *
+ * Returns: AES-256 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecMSCryptoTransformKWAes256GetKlass(void) {
+ return(&xmlSecMSCryptoKWAes256Klass);
+}
+
+#endif /* XMLSEC_NO_AES */
diff --git a/src/mscrypto/crypto.c b/src/mscrypto/crypto.c
index 3fe8d4f..adeaff4 100644
--- a/src/mscrypto/crypto.c
+++ b/src/mscrypto/crypto.c
@@ -121,6 +121,9 @@ xmlSecCryptoGetFunctions_mscrypto(void) {
gXmlSecMSCryptoFunctions->transformAes128CbcGetKlass = xmlSecMSCryptoTransformAes128CbcGetKlass;
gXmlSecMSCryptoFunctions->transformAes192CbcGetKlass = xmlSecMSCryptoTransformAes192CbcGetKlass;
gXmlSecMSCryptoFunctions->transformAes256CbcGetKlass = xmlSecMSCryptoTransformAes256CbcGetKlass;
+ gXmlSecMSCryptoFunctions->transformKWAes128GetKlass = xmlSecMSCryptoTransformKWAes128GetKlass;
+ gXmlSecMSCryptoFunctions->transformKWAes192GetKlass = xmlSecMSCryptoTransformKWAes192GetKlass;
+ gXmlSecMSCryptoFunctions->transformKWAes256GetKlass = xmlSecMSCryptoTransformKWAes256GetKlass;
#endif /* XMLSEC_NO_AES */
/******************************* DES ********************************/
diff --git a/src/openssl/kw_aes.c b/src/openssl/kw_aes.c
index aa76a29..69e99af 100644
--- a/src/openssl/kw_aes.c
+++ b/src/openssl/kw_aes.c
@@ -189,25 +189,33 @@ xmlSecOpenSSLTransformKWAes256GetKlass(void) {
}
-static int
-xmlSecOpenSSLAesBlockEncryptCallback(const xmlSecByte * in, xmlSecByte * out, void * key) {
+static int
+xmlSecOpenSSLAesBlockEncryptCallback(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * key) {
xmlSecAssert2(in != NULL, -1);
+ xmlSecAssert2(inSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(out != NULL, -1);
+ xmlSecAssert2(outSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(key != NULL, -1);
-
+
AES_encrypt(in, out, (AES_KEY*)key);
- return(0);
-}
-
-static int
-xmlSecOpenSSLAesBlockDecryptCallback(const xmlSecByte * in, xmlSecByte * out, void * key) {
+ return(AES_BLOCK_SIZE);
+}
+
+static int
+xmlSecOpenSSLAesBlockDecryptCallback(const xmlSecByte * in, xmlSecSize inSize,
+ xmlSecByte * out, xmlSecSize outSize,
+ void * key) {
xmlSecAssert2(in != NULL, -1);
+ xmlSecAssert2(inSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(out != NULL, -1);
+ xmlSecAssert2(outSize >= AES_BLOCK_SIZE, -1);
xmlSecAssert2(key != NULL, -1);
-
+
AES_decrypt(in, out, (AES_KEY*)key);
- return(0);
-}
+ return(AES_BLOCK_SIZE);
+}
static int
xmlSecOpenSSLKWAesInitialize(xmlSecTransformPtr transform) {
diff --git a/tests/testEnc.sh b/tests/testEnc.sh
index 2d3b2df..54d1ca8 100755
--- a/tests/testEnc.sh
+++ b/tests/testEnc.sh
@@ -69,10 +69,10 @@ execEncTest $res_success \
"--keys-file $keysfile --binary-data $topfolder/aleksey-xmlenc-01/enc-aes256cbc-keyname.data" \
"--keys-file $keysfile"
-execEncTest "aleksey-xmlenc-01/enc-des3cbc-keyname-content" \
- "tripled$res_success \
+execEncTest $res_success \
"" \
- es-cbc" \
+ "aleksey-xmlenc-01/enc-des3cbc-keyname-content" \
+ "tripledes-cbc" \
"--keys-file $topfolder/keys/keys.xml" \
"--keys-file $keysfile --xml-data $topfolder/aleksey-xmlenc-01/enc-des3cbc-keyname-content.data --node-id Test" \
"--keys-file $keysfile"
diff --git a/win32/mycfg.bat b/win32/mycfg.bat
index b1ec8ad..9af468e 100644
--- a/win32/mycfg.bat
+++ b/win32/mycfg.bat
@@ -11,7 +11,7 @@ REM
SET PREFIX=C:\cygwin\home\local
SET XMLSEC_INCLUDE=%PREFIX%\include;%PREFIX%\include\mozilla;%PREFIX%\include\mozilla\nspr;%PREFIX%\include\mozilla\nss;%MSSDK_INCLUDE%
SET XMLSEC_LIB=%PREFIX%\lib;%MSSDK_LIB%
-SET XMLSEC_OPTIONS=static=no iconv=no debug=yes xslt=yes crypto=openssl unicode=yes
+SET XMLSEC_OPTIONS=static=no iconv=no debug=yes xslt=yes crypto=mscrypto,openssl unicode=yes
del /F Makefile configure.txt
cscript configure.js prefix=%PREFIX% %XMLSEC_OPTIONS% include=%XMLSEC_INCLUDE% lib=%XMLSEC_LIB%
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]