|
@@ -1,981 +0,0 @@
|
|
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
|
|
|
- *
|
|
|
|
- * LibTomCrypt is a library that provides various cryptographic
|
|
|
|
- * algorithms in a highly modular and flexible manner.
|
|
|
|
- *
|
|
|
|
- * The library is free for all purposes without any express
|
|
|
|
- * guarantee it works.
|
|
|
|
- *
|
|
|
|
- * Tom St Denis, [email protected], http://libtomcrypt.org
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- @file nlsfast.c
|
|
|
|
- NLS support, entire suite, Tom St Denis
|
|
|
|
-*/
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* Id: nlsfast.c 346 2005-04-22 18:36:12Z mwp */
|
|
|
|
-/* nlsfast: NLS stream cipher and Mundja MAC -- fast implementation */
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
|
|
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND AGAINST
|
|
|
|
-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
|
|
|
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
-*/
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* This source has been modified from the original source for the LibTomCrypt project
|
|
|
|
- * by Tom St Denis. (Warnings fixed and code GNU indented)
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-#include "tomcrypt.h"
|
|
|
|
-
|
|
|
|
-#ifdef NLS_MODE
|
|
|
|
-
|
|
|
|
-#define NLS_LONG_OUTPUT 1
|
|
|
|
-#define N 17
|
|
|
|
-#define NMAC 8
|
|
|
|
-#define WORDSIZE 32
|
|
|
|
-#define F16 0x10001ul
|
|
|
|
-#define MACKONST 8
|
|
|
|
-
|
|
|
|
-/* interface, multiplication table and SBox */
|
|
|
|
-#include "nlssbox.inc"
|
|
|
|
-#include "nlsmultab.inc"
|
|
|
|
-/*
|
|
|
|
- * FOLD is how many register cycles need to be performed after combining the
|
|
|
|
- * last byte of key and non-linear feedback, before every byte depends on every
|
|
|
|
- * byte of the key. This depends on the feedback and nonlinear functions, and
|
|
|
|
- * on where they are combined into the register.
|
|
|
|
- */
|
|
|
|
-#define FOLD N /* how many iterations of folding to do */
|
|
|
|
-#define INITKONST 0x6996c53a /* value of KONST to use during key loading */
|
|
|
|
-#define KEYP 15 /* where to insert key words */
|
|
|
|
-#define FOLDP 4 /* where to insert non-linear feedback */
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
-#define CTRP 2 /* where to insert counter to avoid small cycles */
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
-
|
|
|
|
-#define Byte(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
|
|
|
|
-
|
|
|
|
-/* define IS_LITTLE_ENDIAN for faster operation when appropriate */
|
|
|
|
-#if defined(ENDIAN_LITTLE) && defined(ENDIAN_32BITWORD)
|
|
|
|
-/* Useful macros -- little endian words on a little endian machine */
|
|
|
|
-#define BYTE2WORD(b) (*(ulong32 *)(b))
|
|
|
|
-#define WORD2BYTE(w, b) ((*(ulong32 *)(b)) = w)
|
|
|
|
-#define XORWORD(w, b) ((*(ulong32 *)(b)) ^= w)
|
|
|
|
-#else
|
|
|
|
-/* Useful macros -- machine independent little-endian version */
|
|
|
|
-#define BYTE2WORD(b) ( \
|
|
|
|
- (((ulong32)(b)[3] & 0xFF)<<24) | \
|
|
|
|
- (((ulong32)(b)[2] & 0xFF)<<16) | \
|
|
|
|
- (((ulong32)(b)[1] & 0xFF)<<8) | \
|
|
|
|
- (((ulong32)(b)[0] & 0xFF)) \
|
|
|
|
-)
|
|
|
|
-#define WORD2BYTE(w, b) { \
|
|
|
|
- (b)[3] = Byte(w,3); \
|
|
|
|
- (b)[2] = Byte(w,2); \
|
|
|
|
- (b)[1] = Byte(w,1); \
|
|
|
|
- (b)[0] = Byte(w,0); \
|
|
|
|
-}
|
|
|
|
-#define XORWORD(w, b) { \
|
|
|
|
- (b)[3] ^= Byte(w,3); \
|
|
|
|
- (b)[2] ^= Byte(w,2); \
|
|
|
|
- (b)[1] ^= Byte(w,1); \
|
|
|
|
- (b)[0] ^= Byte(w,0); \
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
-#define ZEROCOUNTER(c) c->CtrModF16 = c->CtrMod232 = 0
|
|
|
|
-#else
|
|
|
|
-#define ZEROCOUNTER(c) /* nothing */
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
-
|
|
|
|
-/* give correct offset for the current position of the register,
|
|
|
|
- * where logically R[0] is at position "zero".
|
|
|
|
- */
|
|
|
|
-#define OFF(zero, i) (((zero)+(i)) % N)
|
|
|
|
-
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
-/* Increment counter and mix into register every so often */
|
|
|
|
-#define FIXCTR(c,z) \
|
|
|
|
-{ \
|
|
|
|
- if (++c->CtrModF16 == F16) { \
|
|
|
|
- c->CtrMod232 += c->CtrModF16; \
|
|
|
|
- c->R[OFF(z,CTRP)] += c->CtrMod232; \
|
|
|
|
- c->CtrMod232 = 0; \
|
|
|
|
- } \
|
|
|
|
-}
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
-
|
|
|
|
-/* step the shift register */
|
|
|
|
-/* After stepping, "zero" moves right one place */
|
|
|
|
-#define STEP(c,z) \
|
|
|
|
- { register ulong32 tt; \
|
|
|
|
- tt = ROL(c->R[OFF(z,0)],19) + ROL(c->R[OFF(z,15)],9) + c->konst; \
|
|
|
|
- tt ^= Sbox[(tt >> 24) & 0xFF]; \
|
|
|
|
- c->R[OFF(z,0)] = tt ^ c->R[OFF(z,4)]; \
|
|
|
|
- }
|
|
|
|
-static void cycle(nls_state * c)
|
|
|
|
-{
|
|
|
|
- ulong32 t;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- /* nonlinear feedback function */
|
|
|
|
- STEP(c, 0);
|
|
|
|
- /* shift register */
|
|
|
|
- t = c->R[0];
|
|
|
|
- for (i = 1; i < N; ++i)
|
|
|
|
- c->R[i - 1] = c->R[i];
|
|
|
|
- c->R[N - 1] = t;
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- FIXCTR(c, 0);
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Return a non-linear function of some parts of the register.
|
|
|
|
- */
|
|
|
|
-#define NLFUNC(c,z) \
|
|
|
|
- (c->R[OFF(z,0)] + c->R[OFF(z,16)]) \
|
|
|
|
- ^ (c->R[OFF(z,1)] + c->konst) \
|
|
|
|
- ^ (c->R[OFF(z,6)] + c->R[OFF(z,13)])
|
|
|
|
-
|
|
|
|
-static ulong32 nltap(nls_state * c)
|
|
|
|
-{
|
|
|
|
- return NLFUNC(c, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* The Mundja MAC function is modelled after the round function of SHA-256.
|
|
|
|
- * The following lines establish aliases for the MAC accumulator, just
|
|
|
|
- * so that the definition of that function looks more like FIPS-180-2.
|
|
|
|
- */
|
|
|
|
-#define A c->M[0]
|
|
|
|
-#define B c->M[1]
|
|
|
|
-#define C c->M[2]
|
|
|
|
-#define D c->M[3]
|
|
|
|
-#define E c->M[4]
|
|
|
|
-#define F c->M[5]
|
|
|
|
-#define G c->M[6]
|
|
|
|
-#define H c->M[7]
|
|
|
|
-#define SIGMA0(x) (ROR((x), 2) ^ ROR((x), 13) ^ ROR((x), 22))
|
|
|
|
-#define SIGMA1(x) (ROR((x), 6) ^ ROR((x), 11) ^ ROR((x), 25))
|
|
|
|
-#define CHOOSE(x,y,z) (z ^ (x & (y ^ z)))
|
|
|
|
-#define MAJORITY(x,y,z) ((x & y) | (z & (x | y)))
|
|
|
|
-
|
|
|
|
-/* Accumulate a nonlinear function of a register word and an input word for MAC.
|
|
|
|
- * Except for the added S-Box and SOBER LFSR input instead of constants,
|
|
|
|
- * this is exactly a round of SHA-256.
|
|
|
|
- */
|
|
|
|
-#define SHAFUNC(c,i,k,A,B,C,D,E,F,G,H) \
|
|
|
|
- { \
|
|
|
|
- ulong32 t1; \
|
|
|
|
- t1 = H + k + i; \
|
|
|
|
- t1 ^= Sbox[(t1 >> 24) & 0xFF]; \
|
|
|
|
- t1 += SIGMA1(E) + CHOOSE(E, F, G); \
|
|
|
|
- D += t1; \
|
|
|
|
- t1 += SIGMA0(A) + MAJORITY(A, B, C); \
|
|
|
|
- H = t1; \
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-static void shafunc(nls_state * c, ulong32 i)
|
|
|
|
-{
|
|
|
|
- ulong32 t;
|
|
|
|
-
|
|
|
|
- SHAFUNC(c, i, c->R[MACKONST], A, B, C, D, E, F, G, H);
|
|
|
|
- /* now correct alignment of MAC accumulator */
|
|
|
|
- t = c->M[NMAC - 1];
|
|
|
|
- for (i = NMAC - 1; i > 0; --i)
|
|
|
|
- c->M[i] = c->M[i - 1];
|
|
|
|
- c->M[0] = t;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Accumulate a CRC of input words, later to be fed into MAC.
|
|
|
|
- */
|
|
|
|
-#define CRCFUNC(c,i,zero,five) \
|
|
|
|
- { \
|
|
|
|
- ulong32 t1; \
|
|
|
|
- t1 = (c->CRC[zero] << 8) ^ Multab[(c->CRC[zero] >> 24) & 0xFF] \
|
|
|
|
- ^ c->CRC[five] ^ i; \
|
|
|
|
- c->CRC[zero] = t1; \
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-static void crcfunc(nls_state * c, ulong32 i)
|
|
|
|
-{
|
|
|
|
- ulong32 t;
|
|
|
|
-
|
|
|
|
- CRCFUNC(c, i, 0, 5);
|
|
|
|
- /* now correct alignment of CRC accumulator */
|
|
|
|
- t = c->CRC[0];
|
|
|
|
- for (i = 1; i < NMAC; ++i)
|
|
|
|
- c->CRC[i - 1] = c->CRC[i];
|
|
|
|
- c->CRC[NMAC - 1] = t;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Normal MAC word processing: do both SHA and CRC.
|
|
|
|
- */
|
|
|
|
-static void macfunc(nls_state * c, ulong32 i)
|
|
|
|
-{
|
|
|
|
- crcfunc(c, i);
|
|
|
|
- shafunc(c, i);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* initialise to known state
|
|
|
|
- */
|
|
|
|
-static void nls_initstate(nls_state * c)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- /* Register initialised to Fibonacci numbers */
|
|
|
|
- c->R[0] = 1;
|
|
|
|
- c->R[1] = 1;
|
|
|
|
- for (i = 2; i < N; ++i)
|
|
|
|
- c->R[i] = c->R[i - 1] + c->R[i - 2];
|
|
|
|
- c->konst = INITKONST;
|
|
|
|
- ZEROCOUNTER(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Save the current register state
|
|
|
|
- */
|
|
|
|
-static void nls_savestate(nls_state * c)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < N; ++i)
|
|
|
|
- c->initR[i] = c->R[i];
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* initialise to previously saved register state
|
|
|
|
- */
|
|
|
|
-static void nls_reloadstate(nls_state * c)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < N; ++i)
|
|
|
|
- c->R[i] = c->initR[i];
|
|
|
|
- ZEROCOUNTER(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Initialise "konst"
|
|
|
|
- */
|
|
|
|
-static void nls_genkonst(nls_state * c)
|
|
|
|
-{
|
|
|
|
- ulong32 newkonst;
|
|
|
|
-
|
|
|
|
- do {
|
|
|
|
- cycle(c);
|
|
|
|
- newkonst = nltap(c);
|
|
|
|
- }
|
|
|
|
- while ((newkonst & 0xFF000000) == 0);
|
|
|
|
- c->konst = newkonst;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Load key material into the register
|
|
|
|
- */
|
|
|
|
-#define ADDKEY(k) \
|
|
|
|
- c->R[KEYP] += (k);
|
|
|
|
-
|
|
|
|
-#define XORNL(nl) \
|
|
|
|
- c->R[FOLDP] ^= (nl);
|
|
|
|
-
|
|
|
|
-/* nonlinear diffusion of register for key and MAC */
|
|
|
|
-#define DROUND(z) STEP(c,z); c->R[OFF((z+1),FOLDP)] ^= NLFUNC(c,(z+1));
|
|
|
|
-static void nls_diffuse(nls_state * c)
|
|
|
|
-{
|
|
|
|
- /* relies on FOLD == N! */
|
|
|
|
- DROUND(0);
|
|
|
|
- DROUND(1);
|
|
|
|
- DROUND(2);
|
|
|
|
- DROUND(3);
|
|
|
|
- DROUND(4);
|
|
|
|
- DROUND(5);
|
|
|
|
- DROUND(6);
|
|
|
|
- DROUND(7);
|
|
|
|
- DROUND(8);
|
|
|
|
- DROUND(9);
|
|
|
|
- DROUND(10);
|
|
|
|
- DROUND(11);
|
|
|
|
- DROUND(12);
|
|
|
|
- DROUND(13);
|
|
|
|
- DROUND(14);
|
|
|
|
- DROUND(15);
|
|
|
|
- DROUND(16);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* common actions for loading key material */
|
|
|
|
-static void
|
|
|
|
-nls_loadkey(nls_state * c, const unsigned char *key, unsigned long keylen)
|
|
|
|
-{
|
|
|
|
- ulong32 i, k;
|
|
|
|
-
|
|
|
|
- /* start folding in key, reject odd sized keys */
|
|
|
|
- if ((keylen & 3) != 0)
|
|
|
|
- abort();
|
|
|
|
- for (i = 0; i < keylen; i += 4) {
|
|
|
|
- k = BYTE2WORD(&key[i]);
|
|
|
|
- ADDKEY(k);
|
|
|
|
- cycle(c);
|
|
|
|
- XORNL(nltap(c));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* also fold in the length of the key */
|
|
|
|
- ADDKEY(keylen);
|
|
|
|
-
|
|
|
|
- /* now diffuse */
|
|
|
|
- nls_diffuse(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* initialise MAC related registers
|
|
|
|
- */
|
|
|
|
-static void nls_macinit(nls_state * c)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < NMAC; ++i) {
|
|
|
|
- c->M[i] = c->R[i];
|
|
|
|
- c->CRC[i] = c->R[i + NMAC];
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Published "key" interface
|
|
|
|
- */
|
|
|
|
-int nls_key(nls_state * c, const unsigned char *key, unsigned long keylen)
|
|
|
|
-{
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(key != NULL);
|
|
|
|
-
|
|
|
|
- if (keylen == 0) {
|
|
|
|
- return CRYPT_INVALID_ARG;
|
|
|
|
- }
|
|
|
|
- nls_initstate(c);
|
|
|
|
- nls_loadkey(c, key, keylen);
|
|
|
|
- nls_genkonst(c);
|
|
|
|
- nls_savestate(c);
|
|
|
|
- nls_macinit(c);
|
|
|
|
- c->nbuf = 0;
|
|
|
|
- ZEROCOUNTER(c);
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Published "nonce" interface
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-nls_nonce(nls_state * c, const unsigned char *nonce, unsigned long noncelen)
|
|
|
|
-{
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(nonce != NULL);
|
|
|
|
- if (noncelen == 0) {
|
|
|
|
- return CRYPT_INVALID_ARG;
|
|
|
|
- }
|
|
|
|
- nls_reloadstate(c);
|
|
|
|
- nls_loadkey(c, nonce, noncelen);
|
|
|
|
- nls_macinit(c);
|
|
|
|
- c->nbuf = 0;
|
|
|
|
- ZEROCOUNTER(c);
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#if 0
|
|
|
|
-/* XOR pseudo-random bytes into buffer
|
|
|
|
- * Note: doesn't play well with MAC functions.
|
|
|
|
- */
|
|
|
|
-#define SROUND(z) STEP(c,z); t = NLFUNC(c,(z+1)); XORWORD(t, buf+(z*4));
|
|
|
|
-static void
|
|
|
|
-nls_stream(nls_state * c, unsigned char *buf, unsigned long nbytes)
|
|
|
|
-{
|
|
|
|
- ulong32 t = 0;
|
|
|
|
-
|
|
|
|
- /* handle any previously buffered bytes */
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- *buf++ ^= c->sbuf & 0xFF;
|
|
|
|
- c->sbuf >>= 8;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do lots at a time, if there's enough to do */
|
|
|
|
- while (nbytes >= N * 4) {
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- if (c->CtrModF16 < (F16 - 17)) {
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- SROUND(0);
|
|
|
|
- SROUND(1);
|
|
|
|
- SROUND(2);
|
|
|
|
- SROUND(3);
|
|
|
|
- SROUND(4);
|
|
|
|
- SROUND(5);
|
|
|
|
- SROUND(6);
|
|
|
|
- SROUND(7);
|
|
|
|
- SROUND(8);
|
|
|
|
- SROUND(9);
|
|
|
|
- SROUND(10);
|
|
|
|
- SROUND(11);
|
|
|
|
- SROUND(12);
|
|
|
|
- SROUND(13);
|
|
|
|
- SROUND(14);
|
|
|
|
- SROUND(15);
|
|
|
|
- SROUND(16);
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- c->CtrModF16 += 17;
|
|
|
|
- } else {
|
|
|
|
- SROUND(0);
|
|
|
|
- FIXCTR(c, 1);
|
|
|
|
- SROUND(1);
|
|
|
|
- FIXCTR(c, 2);
|
|
|
|
- SROUND(2);
|
|
|
|
- FIXCTR(c, 3);
|
|
|
|
- SROUND(3);
|
|
|
|
- FIXCTR(c, 4);
|
|
|
|
- SROUND(4);
|
|
|
|
- FIXCTR(c, 5);
|
|
|
|
- SROUND(5);
|
|
|
|
- FIXCTR(c, 6);
|
|
|
|
- SROUND(6);
|
|
|
|
- FIXCTR(c, 7);
|
|
|
|
- SROUND(7);
|
|
|
|
- FIXCTR(c, 8);
|
|
|
|
- SROUND(8);
|
|
|
|
- FIXCTR(c, 9);
|
|
|
|
- SROUND(9);
|
|
|
|
- FIXCTR(c, 10);
|
|
|
|
- SROUND(10);
|
|
|
|
- FIXCTR(c, 11);
|
|
|
|
- SROUND(11);
|
|
|
|
- FIXCTR(c, 12);
|
|
|
|
- SROUND(12);
|
|
|
|
- FIXCTR(c, 13);
|
|
|
|
- SROUND(13);
|
|
|
|
- FIXCTR(c, 14);
|
|
|
|
- SROUND(14);
|
|
|
|
- FIXCTR(c, 15);
|
|
|
|
- SROUND(15);
|
|
|
|
- FIXCTR(c, 16);
|
|
|
|
- SROUND(16);
|
|
|
|
- FIXCTR(c, 0);
|
|
|
|
- }
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- buf += 4 * N;
|
|
|
|
- nbytes -= N * 4;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do small or odd size buffers the slow way */
|
|
|
|
- while (4 <= nbytes) {
|
|
|
|
- cycle(c);
|
|
|
|
- t = nltap(c);
|
|
|
|
- XORWORD(t, buf);
|
|
|
|
- buf += 4;
|
|
|
|
- nbytes -= 4;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any trailing bytes */
|
|
|
|
- if (nbytes != 0) {
|
|
|
|
- cycle(c);
|
|
|
|
- c->sbuf = nltap(c);
|
|
|
|
- c->nbuf = 32;
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- *buf++ ^= c->sbuf & 0xFF;
|
|
|
|
- c->sbuf >>= 8;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-/* accumulate words into MAC without encryption
|
|
|
|
- * Note that plaintext is accumulated for MAC.
|
|
|
|
- */
|
|
|
|
-#define MROUND(z,A,B,C,D,E,F,G,H) \
|
|
|
|
- t = BYTE2WORD(buf+(z*4)); \
|
|
|
|
- STEP(c,z); \
|
|
|
|
- CRCFUNC(c,t,((z)&0x7),(((z)+5)&0x7)); \
|
|
|
|
- SHAFUNC(c,t,c->R[OFF(z+1,MACKONST)],A,B,C,D,E,F,G,H);
|
|
|
|
-int nls_maconly(nls_state * c, const unsigned char *buf, unsigned long nbytes)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
- ulong32 t = 0;
|
|
|
|
-
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(buf != NULL);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- /* handle any previously buffered bytes */
|
|
|
|
- if (c->nbuf != 0) {
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- c->mbuf ^= (*buf++) << (32 - c->nbuf);
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- if (c->nbuf != 0) { /* not a whole word yet */
|
|
|
|
- return CRYPT_OK;
|
|
|
|
- }
|
|
|
|
- /* LFSR already cycled */
|
|
|
|
- macfunc(c, c->mbuf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do lots at a time, if there's enough to do */
|
|
|
|
- while (4 * N <= nbytes) {
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- if (c->CtrModF16 < (F16 - 17)) {
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- MROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- MROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- MROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- MROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- MROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- MROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- MROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- MROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- MROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- MROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- MROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- MROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- MROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- MROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- MROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- MROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- MROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- c->CtrModF16 += 17;
|
|
|
|
- } else {
|
|
|
|
- MROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 1);
|
|
|
|
- MROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 2);
|
|
|
|
- MROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 3);
|
|
|
|
- MROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 4);
|
|
|
|
- MROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 5);
|
|
|
|
- MROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 6);
|
|
|
|
- MROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 7);
|
|
|
|
- MROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 8);
|
|
|
|
- MROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 9);
|
|
|
|
- MROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 10);
|
|
|
|
- MROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 11);
|
|
|
|
- MROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 12);
|
|
|
|
- MROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 13);
|
|
|
|
- MROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 14);
|
|
|
|
- MROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 15);
|
|
|
|
- MROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 16);
|
|
|
|
- MROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 0);
|
|
|
|
- }
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- buf += 4 * N;
|
|
|
|
- nbytes -= 4 * N;
|
|
|
|
- /* fix alignment of MAC buffer */
|
|
|
|
- t = c->M[NMAC - 1];
|
|
|
|
- for (i = NMAC - 1; i > 0; --i)
|
|
|
|
- c->M[i] = c->M[i - 1];
|
|
|
|
- c->M[0] = t;
|
|
|
|
- /* fix alignment of CRC buffer */
|
|
|
|
- t = c->CRC[0];
|
|
|
|
- for (i = 1; i < NMAC; ++i)
|
|
|
|
- c->CRC[i - 1] = c->CRC[i];
|
|
|
|
- c->CRC[NMAC - 1] = t;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do small or odd size buffers the slow way */
|
|
|
|
- while (4 <= nbytes) {
|
|
|
|
- cycle(c);
|
|
|
|
- macfunc(c, BYTE2WORD(buf));
|
|
|
|
- buf += 4;
|
|
|
|
- nbytes -= 4;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any trailing bytes */
|
|
|
|
- if (nbytes != 0) {
|
|
|
|
- cycle(c);
|
|
|
|
- c->sbuf = nltap(c);
|
|
|
|
- c->mbuf = 0;
|
|
|
|
- c->nbuf = 32;
|
|
|
|
- while (nbytes != 0) {
|
|
|
|
- c->mbuf ^= (*buf++) << (32 - c->nbuf);
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Combined MAC and encryption.
|
|
|
|
- * Note that plaintext is accumulated for MAC.
|
|
|
|
- */
|
|
|
|
-#define EROUND(z,A,B,C,D,E,F,G,H) \
|
|
|
|
- STEP(c,z); \
|
|
|
|
- t3 = BYTE2WORD(buf+(z*4)); \
|
|
|
|
- CRCFUNC(c,t3,((z)&0x7),(((z)+5)&0x7)); \
|
|
|
|
- SHAFUNC(c,t3,c->R[OFF(z+1,MACKONST)],A,B,C,D,E,F,G,H); \
|
|
|
|
- t = NLFUNC(c,(z+1)); \
|
|
|
|
- t ^= t3; \
|
|
|
|
- WORD2BYTE(t,buf+(z*4));
|
|
|
|
-int nls_encrypt(nls_state * c,
|
|
|
|
- const unsigned char *pt, unsigned long nbytes,
|
|
|
|
- unsigned char *ct)
|
|
|
|
-{
|
|
|
|
- ulong32 t = 0, t3 = 0;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(pt != NULL);
|
|
|
|
- LTC_ARGCHK(ct != NULL);
|
|
|
|
-
|
|
|
|
- #define buf ct
|
|
|
|
-
|
|
|
|
- /* do copy as required */
|
|
|
|
- if (pt != ct) {
|
|
|
|
- XMEMCPY(ct, pt, nbytes);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any previously buffered bytes */
|
|
|
|
- if (c->nbuf != 0) {
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- c->mbuf ^= *buf << (32 - c->nbuf);
|
|
|
|
- *buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
|
|
|
- ++buf;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- if (c->nbuf != 0) /* not a whole word yet */
|
|
|
|
- return CRYPT_OK;
|
|
|
|
- /* LFSR already cycled */
|
|
|
|
- macfunc(c, c->mbuf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do lots at a time, if there's enough to do */
|
|
|
|
- while (4 * N <= nbytes) {
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- if (c->CtrModF16 < (F16 - 17)) {
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- EROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- EROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- EROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- EROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- EROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- EROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- EROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- EROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- EROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- EROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- EROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- EROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- EROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- EROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- EROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- EROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- EROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- c->CtrModF16 += 17;
|
|
|
|
- } else {
|
|
|
|
- EROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 1);
|
|
|
|
- EROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 2);
|
|
|
|
- EROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 3);
|
|
|
|
- EROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 4);
|
|
|
|
- EROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 5);
|
|
|
|
- EROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 6);
|
|
|
|
- EROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 7);
|
|
|
|
- EROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 8);
|
|
|
|
- EROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 9);
|
|
|
|
- EROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 10);
|
|
|
|
- EROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 11);
|
|
|
|
- EROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 12);
|
|
|
|
- EROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 13);
|
|
|
|
- EROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 14);
|
|
|
|
- EROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 15);
|
|
|
|
- EROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 16);
|
|
|
|
- EROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 0);
|
|
|
|
- }
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- buf += 4 * N;
|
|
|
|
- nbytes -= 4 * N;
|
|
|
|
- /* fix alignment of MAC buffer */
|
|
|
|
- t = c->M[7];
|
|
|
|
- for (i = NMAC - 1; i > 0; --i)
|
|
|
|
- c->M[i] = c->M[i - 1];
|
|
|
|
- c->M[0] = t;
|
|
|
|
- /* fix alignment of CRC buffer */
|
|
|
|
- t = c->CRC[0];
|
|
|
|
- for (i = 1; i < NMAC; ++i)
|
|
|
|
- c->CRC[i - 1] = c->CRC[i];
|
|
|
|
- c->CRC[NMAC - 1] = t;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do small or odd size buffers the slow way */
|
|
|
|
- while (4 <= nbytes) {
|
|
|
|
- cycle(c);
|
|
|
|
- t = BYTE2WORD(buf);
|
|
|
|
- macfunc(c, t);
|
|
|
|
- t ^= nltap(c);
|
|
|
|
- WORD2BYTE(t, buf);
|
|
|
|
- nbytes -= 4;
|
|
|
|
- buf += 4;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any trailing bytes */
|
|
|
|
- if (nbytes != 0) {
|
|
|
|
- cycle(c);
|
|
|
|
- c->sbuf = nltap(c);
|
|
|
|
- c->mbuf = 0;
|
|
|
|
- c->nbuf = 32;
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- c->mbuf ^= *buf << (32 - c->nbuf);
|
|
|
|
- *buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
|
|
|
- ++buf;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- #undef buf
|
|
|
|
-
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Combined MAC and decryption.
|
|
|
|
- * Note that plaintext is accumulated for MAC.
|
|
|
|
- */
|
|
|
|
-#undef DROUND
|
|
|
|
-#define DROUND(z,A,B,C,D,E,F,G,H) \
|
|
|
|
- STEP(c,z); \
|
|
|
|
- t = NLFUNC(c,(z+1)); \
|
|
|
|
- t3 = BYTE2WORD(buf+(z*4)); \
|
|
|
|
- t ^= t3; \
|
|
|
|
- CRCFUNC(c,t,((z)&0x7),(((z)+5)&0x7)); \
|
|
|
|
- SHAFUNC(c,t,c->R[OFF(z+1,MACKONST)],A,B,C,D,E,F,G,H); \
|
|
|
|
- WORD2BYTE(t, buf+(z*4));
|
|
|
|
-int nls_decrypt(nls_state * c,
|
|
|
|
- const unsigned char *ct, unsigned long nbytes,
|
|
|
|
- unsigned char *pt)
|
|
|
|
-{
|
|
|
|
- ulong32 t = 0, t3 = 0;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(pt != NULL);
|
|
|
|
- LTC_ARGCHK(ct != NULL);
|
|
|
|
-
|
|
|
|
- #define buf pt
|
|
|
|
-
|
|
|
|
- if (pt != ct) {
|
|
|
|
- XMEMCPY(pt, ct, nbytes);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any previously buffered bytes */
|
|
|
|
- if (c->nbuf != 0) {
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- *buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
|
|
|
- c->mbuf ^= *buf << (32 - c->nbuf);
|
|
|
|
- ++buf;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- if (c->nbuf != 0) /* not a whole word yet */
|
|
|
|
- return CRYPT_OK;
|
|
|
|
- /* LFSR already cycled */
|
|
|
|
- macfunc(c, c->mbuf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* now do lots at a time, if there's enough */
|
|
|
|
- while (4 * N <= nbytes) {
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- if (c->CtrModF16 < (F16 - 17)) {
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- DROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- DROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- DROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- DROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- DROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- DROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- DROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- DROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- DROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- DROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- DROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- DROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- DROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- DROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- DROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- DROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- DROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
-#if NLS_LONG_OUTPUT
|
|
|
|
- c->CtrModF16 += 17;
|
|
|
|
- } else {
|
|
|
|
- DROUND(0, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 1);
|
|
|
|
- DROUND(1, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 2);
|
|
|
|
- DROUND(2, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 3);
|
|
|
|
- DROUND(3, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 4);
|
|
|
|
- DROUND(4, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 5);
|
|
|
|
- DROUND(5, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 6);
|
|
|
|
- DROUND(6, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 7);
|
|
|
|
- DROUND(7, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 8);
|
|
|
|
- DROUND(8, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 9);
|
|
|
|
- DROUND(9, H, A, B, C, D, E, F, G);
|
|
|
|
- FIXCTR(c, 10);
|
|
|
|
- DROUND(10, G, H, A, B, C, D, E, F);
|
|
|
|
- FIXCTR(c, 11);
|
|
|
|
- DROUND(11, F, G, H, A, B, C, D, E);
|
|
|
|
- FIXCTR(c, 12);
|
|
|
|
- DROUND(12, E, F, G, H, A, B, C, D);
|
|
|
|
- FIXCTR(c, 13);
|
|
|
|
- DROUND(13, D, E, F, G, H, A, B, C);
|
|
|
|
- FIXCTR(c, 14);
|
|
|
|
- DROUND(14, C, D, E, F, G, H, A, B);
|
|
|
|
- FIXCTR(c, 15);
|
|
|
|
- DROUND(15, B, C, D, E, F, G, H, A);
|
|
|
|
- FIXCTR(c, 16);
|
|
|
|
- DROUND(16, A, B, C, D, E, F, G, H);
|
|
|
|
- FIXCTR(c, 0);
|
|
|
|
- }
|
|
|
|
-#endif /*NLS_LONG_OUTPUT */
|
|
|
|
- buf += 4 * N;
|
|
|
|
- nbytes -= 4 * N;
|
|
|
|
- /* fix alignment of MAC buffer */
|
|
|
|
- t = c->M[7];
|
|
|
|
- for (i = NMAC - 1; i > 0; --i)
|
|
|
|
- c->M[i] = c->M[i - 1];
|
|
|
|
- c->M[0] = t;
|
|
|
|
- /* fix alignment of CRC buffer */
|
|
|
|
- t = c->CRC[0];
|
|
|
|
- for (i = 1; i < NMAC; ++i)
|
|
|
|
- c->CRC[i - 1] = c->CRC[i];
|
|
|
|
- c->CRC[NMAC - 1] = t;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* do small or odd size buffers the slow way */
|
|
|
|
- while (4 <= nbytes) {
|
|
|
|
- cycle(c);
|
|
|
|
- t = nltap(c);
|
|
|
|
- t3 = BYTE2WORD(buf);
|
|
|
|
- t ^= t3;
|
|
|
|
- macfunc(c, t);
|
|
|
|
- WORD2BYTE(t, buf);
|
|
|
|
- nbytes -= 4;
|
|
|
|
- buf += 4;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* handle any trailing bytes */
|
|
|
|
- if (nbytes != 0) {
|
|
|
|
- cycle(c);
|
|
|
|
- c->sbuf = nltap(c);
|
|
|
|
- c->mbuf = 0;
|
|
|
|
- c->nbuf = 32;
|
|
|
|
- while (c->nbuf != 0 && nbytes != 0) {
|
|
|
|
- *buf ^= (c->sbuf >> (32 - c->nbuf)) & 0xFF;
|
|
|
|
- c->mbuf ^= *buf << (32 - c->nbuf);
|
|
|
|
- ++buf;
|
|
|
|
- c->nbuf -= 8;
|
|
|
|
- --nbytes;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-
|
|
|
|
- #undef buf
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Having accumulated a MAC, finish processing and return it.
|
|
|
|
- * Note that any unprocessed bytes are treated as if
|
|
|
|
- * they were encrypted zero bytes, so plaintext (zero) is accumulated.
|
|
|
|
- */
|
|
|
|
-int nls_finish(nls_state * c, unsigned char *buf, unsigned long nbytes)
|
|
|
|
-{
|
|
|
|
- ulong32 i;
|
|
|
|
-
|
|
|
|
- LTC_ARGCHK(c != NULL);
|
|
|
|
- LTC_ARGCHK(buf != NULL);
|
|
|
|
-
|
|
|
|
- /* handle any previously buffered bytes */
|
|
|
|
- if (c->nbuf != 0) {
|
|
|
|
- /* LFSR already cycled */
|
|
|
|
- macfunc(c, c->mbuf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* perturb the MAC to mark end of input.
|
|
|
|
- * Note that only the SHA part is updated, not the CRC. This is an
|
|
|
|
- * action that can't be duplicated by passing in plaintext, hence
|
|
|
|
- * defeating any kind of extension attack.
|
|
|
|
- */
|
|
|
|
- cycle(c);
|
|
|
|
- shafunc(c, INITKONST + (c->nbuf << 24));
|
|
|
|
- c->nbuf = 0;
|
|
|
|
-
|
|
|
|
- /* now add the CRC to the MAC like input material */
|
|
|
|
- for (i = 0; i < NMAC; ++i) {
|
|
|
|
- cycle(c);
|
|
|
|
- crcfunc(c, 0);
|
|
|
|
- shafunc(c, c->CRC[7]);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* continue that process, producing output from the MAC buffer */
|
|
|
|
- while (nbytes > 0) {
|
|
|
|
- cycle(c);
|
|
|
|
- crcfunc(c, 0);
|
|
|
|
- shafunc(c, c->CRC[7]);
|
|
|
|
- if (nbytes >= 4) {
|
|
|
|
- WORD2BYTE(A, buf);
|
|
|
|
- nbytes -= 4;
|
|
|
|
- buf += 4;
|
|
|
|
- } else {
|
|
|
|
- for (i = 0; i < nbytes; ++i)
|
|
|
|
- buf[i] = Byte(A, i);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return CRYPT_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-/* $Source$ */
|
|
|
|
-/* $Revision$ */
|
|
|
|
-/* $Date$ */
|
|
|