seccbce.c revision 40f53fa8d9c6a4fc38c0014495e7a42b08f52481
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews unpublished work protected as such under copyright law. This work
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence contains proprietary, confidential, and trade secret information of
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews RSA Data Security, Inc. Use, disclosure or reproduction without the
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews express written authorization of RSA Data Security, Inc. is
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews prohibited.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
4b6dc226f78862286daa69fba761eac9fd5da16aAutomatic Updater#include "global.h"
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister#include "algae.h"
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister#include "secrcbc.h"
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews/* On first call, it is assumed that *remainderLen is zero.
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews Returns AE_OUTPUT_LEN, 0.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
6324997211a5e2d82528dcde98e8981190a35faeMichael Graffint SecretCBCEncryptUpdate
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff (context, xorBlock, remainder, remainderLen, SecretEncrypt, output,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff outputLen, maxOutputLen, input, inputLen)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David LawrencePOINTER context;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsunsigned char *xorBlock;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsunsigned char *remainder;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsunsigned int *remainderLen;
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark AndrewsSECRET_CRYPT SecretEncrypt;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsunsigned char *output;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsunsigned int *outputLen;
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaramanunsigned int maxOutputLen;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrewsunsigned char *input;
ae114ded82e773a4d9058f833f964a17514712a8Brian Wellingtonunsigned int inputLen;
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister{
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews unsigned int partialLen, totalLen, i;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e0a30050c8516a3d54a4f8dcdd88435704a8a3edMark Andrews totalLen = *remainderLen + inputLen;
e0a30050c8516a3d54a4f8dcdd88435704a8a3edMark Andrews
e0a30050c8516a3d54a4f8dcdd88435704a8a3edMark Andrews /* Output length will be all available 8-byte blocks.
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson */
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington if ((*outputLen = 8 * (totalLen / 8)) > maxOutputLen)
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington return (AE_OUTPUT_LEN);
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews if (totalLen < 8) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence /* Not enough to encrypt, just accumulate into remainder.
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews T_memcpy
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews *remainderLen = totalLen;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (0);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /* Accumulate enough bytes from input into remainder to encrypt the
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews remainder.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews T_memcpy
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ((POINTER)remainder + *remainderLen, (POINTER)input,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff partialLen = 8 - *remainderLen);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (i = 0; i < 8; i++)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews output[i] = remainder[i] ^ xorBlock[i];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Encrypt in place */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (*SecretEncrypt) (context, output, output);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews T_memcpy ((POINTER)xorBlock, (POINTER)output, 8);
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman input += partialLen;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews inputLen -= partialLen;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews output += 8;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Now encrypt the bulk of the input.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (inputLen >= 8) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (i = 0; i < 8; i++)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews output[i] = *(input++) ^ xorBlock[i];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Encrypt in place */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (*SecretEncrypt) (context, output, output);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews T_memcpy ((POINTER)xorBlock, (POINTER)output, 8);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews output += 8;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews inputLen -= 8;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* inputLen is now < 8, so copy input to remainder.
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews T_memcpy ((POINTER)remainder, (POINTER)input, inputLen);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews *remainderLen = inputLen;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (0);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/* This just ensures that *remainderLen is zero.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff The caller must restart the context (setting remainderLen to zero).
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence Returns AE_INPUT_LEN, 0.
4b6dc226f78862286daa69fba761eac9fd5da16aAutomatic Updater */
4b6dc226f78862286daa69fba761eac9fd5da16aAutomatic Updaterint SecretCBCEncryptFinal (remainderLen)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrenceunsigned int remainderLen;
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman{
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews if (remainderLen != 0)
ae114ded82e773a4d9058f833f964a17514712a8Brian Wellington return (AE_INPUT_LEN);
ce8b84ce64a7f1b3b7b558a4aa14be946846080aJames Brister
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (0);
ae114ded82e773a4d9058f833f964a17514712a8Brian Wellington}
ae114ded82e773a4d9058f833f964a17514712a8Brian Wellington