mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-27 17:17:22 -04:00
146 lines
4.1 KiB
C
146 lines
4.1 KiB
C
/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
|
|
unpublished work protected as such under copyright law. This work
|
|
contains proprietary, confidential, and trade secret information of
|
|
RSA Data Security, Inc. Use, disclosure or reproduction without the
|
|
express written authorization of RSA Data Security, Inc. is
|
|
prohibited.
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "algae.h"
|
|
#include "secrcbc.h"
|
|
|
|
static void SecretCBCDecryptBlock PROTO_LIST
|
|
((POINTER, unsigned char *, SECRET_CRYPT, unsigned char *,
|
|
unsigned char *));
|
|
|
|
/* On first call, it is assumed that *remainderLen is zero.
|
|
This assumes remainder buffer is at least 16 bytes is size.
|
|
Returns AE_OUTPUT_LEN, 0.
|
|
*/
|
|
int SecretCBCDecryptUpdate
|
|
(context, xorBlock, remainder, remainderLen, SecretDecrypt, output,
|
|
outputLen, maxOutputLen, input, inputLen)
|
|
POINTER context;
|
|
unsigned char *xorBlock;
|
|
unsigned char *remainder;
|
|
unsigned int *remainderLen;
|
|
SECRET_CRYPT SecretDecrypt;
|
|
unsigned char *output;
|
|
unsigned int *outputLen;
|
|
unsigned int maxOutputLen;
|
|
unsigned char *input;
|
|
unsigned int inputLen;
|
|
{
|
|
unsigned int partialLen;
|
|
|
|
if (*remainderLen + inputLen <= 16) {
|
|
/* Not enough to decrypt, just accumulate into remainder.
|
|
*/
|
|
*outputLen = 0;
|
|
T_memcpy ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen);
|
|
*remainderLen += inputLen;
|
|
return (0);
|
|
}
|
|
|
|
/* Fill up the rest of the remainder with bytes from input.
|
|
*/
|
|
T_memcpy
|
|
((POINTER)remainder + *remainderLen, (POINTER)input,
|
|
partialLen = 16 - *remainderLen);
|
|
input += partialLen;
|
|
inputLen -= partialLen;
|
|
|
|
/* remainder is full and inputLen is at least 1. Compute outputLen
|
|
as the size needed to keep remainder as full as possible.
|
|
*/
|
|
if ((*outputLen = 8 * ((inputLen + 7) / 8)) > maxOutputLen)
|
|
return (AE_OUTPUT_LEN);
|
|
|
|
SecretCBCDecryptBlock
|
|
(context, xorBlock, SecretDecrypt, output, remainder);
|
|
output += 8;
|
|
|
|
if (inputLen <= 8) {
|
|
/* Shift remaining input bytes into remainder */
|
|
T_memmove ((POINTER)remainder, (POINTER)(remainder + 8), 8);
|
|
T_memcpy ((POINTER)(remainder + 8), (POINTER)input, inputLen);
|
|
*remainderLen = 8 + inputLen;
|
|
return (0);
|
|
}
|
|
|
|
/* Decrypt the rest of the remainder.
|
|
*/
|
|
SecretCBCDecryptBlock
|
|
(context, xorBlock, SecretDecrypt, output, remainder + 8);
|
|
output += 8;
|
|
|
|
/* Now decrypt the bulk of the input.
|
|
*/
|
|
while (inputLen > 16) {
|
|
SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, output, input);
|
|
output += 8;
|
|
input += 8;
|
|
inputLen -= 8;
|
|
}
|
|
|
|
/* inputLen is now <= 16, so copy input to remainder.
|
|
*/
|
|
T_memcpy ((POINTER)remainder, (POINTER)input, inputLen);
|
|
*remainderLen = inputLen;
|
|
return (0);
|
|
}
|
|
|
|
/* The caller must restart the context (setting remainderLen to zero).
|
|
Returns AE_INPUT_LEN, AE_OUTPUT_LEN, 0.
|
|
*/
|
|
int SecretCBCDecryptFinal
|
|
(context, xorBlock, remainder, remainderLen, SecretDecrypt, output,
|
|
outputLen, maxOutputLen)
|
|
POINTER context;
|
|
unsigned char *xorBlock;
|
|
unsigned char *remainder;
|
|
unsigned int remainderLen;
|
|
SECRET_CRYPT SecretDecrypt;
|
|
unsigned char *output;
|
|
unsigned int *outputLen;
|
|
unsigned int maxOutputLen;
|
|
{
|
|
if ((*outputLen = remainderLen) == 0)
|
|
/* There was never any data. */
|
|
return (0);
|
|
|
|
if (remainderLen != 8 && remainderLen != 16)
|
|
return (AE_INPUT_LEN);
|
|
|
|
if (*outputLen > maxOutputLen)
|
|
return (AE_OUTPUT_LEN);
|
|
|
|
SecretCBCDecryptBlock
|
|
(context, xorBlock, SecretDecrypt, output, remainder);
|
|
output += 8;
|
|
if (remainderLen == 16)
|
|
SecretCBCDecryptBlock
|
|
(context, xorBlock, SecretDecrypt, output, remainder + 8);
|
|
return (0);
|
|
}
|
|
|
|
static void SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, out, in)
|
|
POINTER context;
|
|
unsigned char *xorBlock;
|
|
SECRET_CRYPT SecretDecrypt;
|
|
unsigned char *out;
|
|
unsigned char *in;
|
|
{
|
|
unsigned char tempBuffer[8];
|
|
unsigned int i;
|
|
|
|
/* Save input to be copied to the xor block. */
|
|
T_memcpy ((POINTER)tempBuffer, (POINTER)in, 8);
|
|
(*SecretDecrypt) (context, out, in);
|
|
for (i = 0; i < 8; i++)
|
|
out[i] ^= xorBlock[i];
|
|
T_memcpy ((POINTER)xorBlock, (POINTER)tempBuffer, 8);
|
|
|
|
T_memset ((POINTER)tempBuffer, 0, sizeof (tempBuffer));
|
|
}
|