static int xmlSecNSSKWAesBlockDecrypt(const xmlSecByte * in, xmlSecSize inSize, xmlSecByte * out, xmlSecSize outSize, void * context) { PK11SymKey *aeskey = (PK11SymKey *)context; int ret; xmlSecAssert2(in != NULL, -1); xmlSecAssert2(inSize >= XMLSEC_KW_AES_BLOCK_SIZE, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize >= XMLSEC_KW_AES_BLOCK_SIZE, -1); xmlSecAssert2(aeskey != NULL, -1); /* one block */ ret = xmlSecNssAesOp(aeskey, in, out, 0); /* decrypt */ if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecNssAesOp", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(XMLSEC_KW_AES_BLOCK_SIZE); }
static int xmlSecNssKWAesOp(const xmlSecByte *key, xmlSecSize keySize, const xmlSecByte *in, xmlSecSize inSize, xmlSecByte *out, xmlSecSize outSize, int enc) { xmlSecByte block[XMLSEC_NSS_AES_BLOCK_SIZE]; xmlSecByte *p; int N, i, j, t; int result = -1; PK11SymKey *aeskey = NULL; xmlSecAssert2(key != NULL, -1); xmlSecAssert2(keySize > 0, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(inSize > 0, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize >= inSize + 8, -1); if (enc == 1) { aeskey = xmlSecNssMakeAesKey(key, keySize, enc); if(aeskey == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecNssMakeAesKey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } /* prepend magic block */ if(in != out) { memcpy(out + XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE, in, inSize); } else { memmove(out + XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE, out, inSize); } memcpy(out, xmlSecNssKWAesMagicBlock, XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE); N = (inSize / 8); if(N == 1) { xmlSecNssAesOp(aeskey, out, out, enc); } 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); xmlSecNssAesOp(aeskey, block, block, enc); block[7] ^= t; memcpy(out, block, 8); memcpy(p, block + 8, 8); } } } result = inSize + 8; } else { aeskey = xmlSecNssMakeAesKey(key, keySize, enc); if(aeskey == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecNssMakeAesKey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } /* copy input */ if(in != out) { memcpy(out, in, inSize); } N = (inSize / 8) - 1; if(N == 1) { xmlSecNssAesOp(aeskey, out, out, enc); } 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; xmlSecNssAesOp(aeskey, block, block, enc); memcpy(out, block, 8); memcpy(p, block + 8, 8); } } } /* do not left data in memory */ memset(block, 0, sizeof(block)); if(memcmp(xmlSecNssKWAesMagicBlock, out, XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE) != 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_DATA, "bad magic block"); goto done; } memmove(out, out + XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE, inSize - XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE); result = (inSize - XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE); } done: if (aeskey != NULL) { PK11_FreeSymKey(aeskey); } return (result); }