rpm/beecrypt/fips186.c

219 lines
4.9 KiB
C

/** \ingroup PRNG_fips186_m DSA_m
* \file fips186.c
*
* NIST FIPS-186 pseudo-random generator, code.
*/
/*
* Copyright (c) 1998, 1999, 2000 Virtual Unlimited B.V.
*
* Author: Bob Deblier <bob@virtualunlimited.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "system.h"
#include "beecrypt.h"
#include "fips186.h"
#include "mp32opt.h"
#include "mp32.h"
#include "debug.h"
/**
*/
/*@observer@*/ /*@unchecked@*/
static uint32 fips186hinit[5] = { 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, 0x67452301 };
/*@-sizeoftype@*/
const randomGenerator fips186prng = { "FIPS 186", sizeof(fips186Param), (const randomGeneratorSetup) fips186Setup, (const randomGeneratorSeed) fips186Seed, (const randomGeneratorNext) fips186Next, (const randomGeneratorCleanup) fips186Cleanup };
/*@=sizeoftype@*/
/**
*/
/*@-boundswrite@*/
static int fips186init(register sha1Param* p)
/*@modifies p @*/
{
mp32copy(5, p->h, fips186hinit);
return 0;
}
/*@=boundswrite@*/
int fips186Setup(fips186Param* fp)
{
if (fp)
{
#ifdef _REENTRANT
# if WIN32
if (!(fp->lock = CreateMutex(NULL, FALSE, NULL)))
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_init(&fp->lock, USYNC_THREAD, (void *) 0))
return -1;
# elif HAVE_PTHREAD_H
/*@-nullpass@*/
/*@-moduncon@*/
if (pthread_mutex_init(&fp->lock, (pthread_mutexattr_t *) 0))
return -1;
/*@=moduncon@*/
/*@=nullpass@*/
# endif
# endif
#endif
fp->digestsize = 0;
return entropyGatherNext(fp->state, FIPS186_STATE_SIZE);
}
return -1;
}
int fips186Seed(fips186Param* fp, const uint32* data, int size)
{
if (fp)
{
#ifdef _REENTRANT
# if WIN32
if (WaitForSingleObject(fp->lock, INFINITE) != WAIT_OBJECT_0)
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_lock(&fp->lock))
return -1;
# elif HAVE_PTHREAD_H
/*@-moduncon@*/
if (pthread_mutex_lock(&fp->lock))
return -1;
/*@=moduncon@*/
# endif
# endif
#endif
if (data)
(void) mp32addx(FIPS186_STATE_SIZE, fp->state, size, data);
#ifdef _REENTRANT
# if WIN32
if (!ReleaseMutex(fp->lock))
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_unlock(&fp->lock))
return -1;
# elif HAVE_PTHREAD_H
/*@-moduncon@*/
if (pthread_mutex_unlock(&fp->lock))
return -1;
/*@=moduncon@*/
# endif
# endif
#endif
return 0;
}
return -1;
}
/*@-boundswrite@*/
int fips186Next(fips186Param* fp, uint32* data, int size)
{
if (fp)
{
#ifdef _REENTRANT
# if WIN32
if (WaitForSingleObject(fp->lock, INFINITE) != WAIT_OBJECT_0)
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_lock(&fp->lock))
return -1;
# elif HAVE_PTHREAD_H
/*@-moduncon@*/
if (pthread_mutex_lock(&fp->lock))
return -1;
/*@=moduncon@*/
# endif
# endif
#endif
while (size > 0)
{
register uint32 copy;
if (fp->digestsize == 0)
{
(void) fips186init(&fp->param);
/* copy the 512 bits of state data into the sha1Param */
mp32copy(FIPS186_STATE_SIZE, fp->param.data, fp->state);
/* process the data */
sha1Process(&fp->param);
/* set state to state + digest + 1 mod 2^512 */
(void) mp32addx(FIPS186_STATE_SIZE, fp->state, 5, fp->param.h);
(void) mp32addw(FIPS186_STATE_SIZE, fp->state, 1);
/* we now have 5 words of pseudo-random data */
fp->digestsize = 5;
}
copy = (size > fp->digestsize) ? fp->digestsize : size;
mp32copy(copy, data, fp->param.h + 5 - fp->digestsize);
fp->digestsize -= copy;
size -= copy;
data += copy;
}
#ifdef _REENTRANT
# if WIN32
if (!ReleaseMutex(fp->lock))
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_unlock(&fp->lock))
return -1;
# elif HAVE_PTHREAD_H
/*@-moduncon@*/
if (pthread_mutex_unlock(&fp->lock))
return -1;
/*@=moduncon@*/
# endif
# endif
#endif
return 0;
}
return -1;
}
/*@=boundswrite@*/
int fips186Cleanup(fips186Param* fp)
{
if (fp)
{
#ifdef _REENTRANT
# if WIN32
if (!CloseHandle(fp->lock))
return -1;
# else
# if HAVE_THREAD_H && HAVE_SYNCH_H
if (mutex_destroy(&fp->lock))
return -1;
# elif HAVE_PTHREAD_H
/*@-moduncon@*/
if (pthread_mutex_destroy(&fp->lock))
return -1;
/*@=moduncon@*/
# endif
# endif
#endif
return 0;
}
return -1;
}