193 | 193 |
/* ======================================================================== */
|
194 | 194 |
|
195 | 195 |
/*
|
196 | |
* Key schedule: initialize the key context structure with the provided
|
197 | |
* secret key. The secret key is an array of 1 to 32 bytes.
|
|
196 |
* Initialize Sosemanuk's state by providing a key. The key is an array of
|
|
197 |
* 1 to 32 bytes.
|
198 | 198 |
* @param ss The Sosemanuk state
|
199 | 199 |
* @param key Key
|
200 | |
* @param keylen Length of key
|
|
200 |
* @param keylen Length of key in bytes
|
201 | 201 |
* @return CRYPT_OK on success
|
202 | 202 |
*/
|
203 | 203 |
int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long keylen)
|
|
330 | 330 |
|
331 | 331 |
|
332 | 332 |
/*
|
333 | |
* Cipher initialization: the cipher internal state is initialized, using
|
334 | |
* the provided key context and IV. The IV length is up to 16 bytes. If
|
335 | |
* "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.
|
|
333 |
* Initialization continues by setting the IV. The IV length is up to 16 bytes.
|
|
334 |
* If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL. If multiple
|
|
335 |
* encryptions/decryptions are to be performed with the same key and
|
|
336 |
* sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
|
|
337 |
* to set the state.
|
336 | 338 |
* @param ss The Sosemanuk state
|
337 | 339 |
* @param iv Initialization vector
|
338 | |
* @param ivlen Length of iv
|
|
340 |
* @param ivlen Length of iv in bytes
|
339 | 341 |
* @return CRYPT_OK on success
|
340 | 342 |
*/
|
341 | 343 |
int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
|
|
379 | 381 |
unsigned char ivtmp[16] = {0};
|
380 | 382 |
|
381 | 383 |
LTC_ARGCHK(ss != NULL);
|
382 | |
LTC_ARGCHK(ivlen >= 0 && ivlen <= 16);
|
|
384 |
LTC_ARGCHK(ivlen <= 16);
|
383 | 385 |
LTC_ARGCHK(iv != NULL || ivlen == 0);
|
384 | 386 |
|
385 | 387 |
if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
|
|
447 | 449 |
/*
|
448 | 450 |
* Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
|
449 | 451 |
*/
|
450 | |
static ulong32 mul_a[] = {
|
|
452 |
static const ulong32 mul_a[] = {
|
451 | 453 |
0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835,
|
452 | 454 |
0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679,
|
453 | 455 |
0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD,
|
|
517 | 519 |
/*
|
518 | 520 |
* Multiplication by 1/alpha: 1/alpha * x = (x >> 8) ^ mul_ia[x & 0xFF]
|
519 | 521 |
*/
|
520 | |
static ulong32 mul_ia[] = {
|
|
522 |
static const ulong32 mul_ia[] = {
|
521 | 523 |
0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE,
|
522 | 524 |
0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998,
|
523 | 525 |
0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32,
|
|
742 | 744 |
* reference distinct buffers (no partial overlap is allowed).
|
743 | 745 |
* @param ss The Sosemanuk state
|
744 | 746 |
* @param in Data in
|
|
747 |
* @param inlen Length of data in bytes
|
745 | 748 |
* @param out Data out
|
746 | |
* @param datalen Length of data
|
747 | 749 |
* @return CRYPT_OK on success
|
748 | 750 |
*/
|
749 | 751 |
int sosemanuk_crypt(sosemanuk_state *ss,
|
750 | |
const unsigned char *in, unsigned long datalen, unsigned char *out)
|
|
752 |
const unsigned char *in, unsigned long inlen, unsigned char *out)
|
751 | 753 |
{
|
752 | 754 |
LTC_ARGCHK(ss != NULL);
|
753 | 755 |
LTC_ARGCHK(in != NULL);
|
|
756 | 758 |
if (ss->ptr < (sizeof(ss->buf))) {
|
757 | 759 |
unsigned long rlen = (sizeof(ss->buf)) - ss->ptr;
|
758 | 760 |
|
759 | |
if (rlen > datalen)
|
760 | |
rlen = datalen;
|
|
761 |
if (rlen > inlen)
|
|
762 |
rlen = inlen;
|
761 | 763 |
_xorbuf(ss->buf + ss->ptr, in, out, rlen);
|
762 | 764 |
in += rlen;
|
763 | 765 |
out += rlen;
|
764 | |
datalen -= rlen;
|
|
766 |
inlen -= rlen;
|
765 | 767 |
ss->ptr += rlen;
|
766 | 768 |
}
|
767 | |
while (datalen > 0) {
|
|
769 |
while (inlen > 0) {
|
768 | 770 |
_sosemanuk_internal(ss);
|
769 | |
if (datalen >= sizeof(ss->buf)) {
|
|
771 |
if (inlen >= sizeof(ss->buf)) {
|
770 | 772 |
_xorbuf(ss->buf, in, out, sizeof(ss->buf));
|
771 | 773 |
in += sizeof(ss->buf);
|
772 | 774 |
out += sizeof(ss->buf);
|
773 | |
datalen -= sizeof(ss->buf);
|
|
775 |
inlen -= sizeof(ss->buf);
|
774 | 776 |
} else {
|
775 | |
_xorbuf(ss->buf, in, out, datalen);
|
776 | |
ss->ptr = datalen;
|
777 | |
datalen = 0;
|
|
777 |
_xorbuf(ss->buf, in, out, inlen);
|
|
778 |
ss->ptr = inlen;
|
|
779 |
inlen = 0;
|
778 | 780 |
}
|
779 | 781 |
}
|
780 | 782 |
return CRYPT_OK;
|
781 | 783 |
}
|
782 | 784 |
|
783 | 785 |
|
|
786 |
|
784 | 787 |
/*
|
785 | 788 |
* Cipher operation, as a PRNG: the provided output buffer is filled with
|
786 | 789 |
* pseudo-random bytes as output from the stream cipher.
|
787 | 790 |
* @param ss The Sosemanuk state
|
788 | 791 |
* @param out Data out
|
789 | |
* @param outlen Length of output
|
|
792 |
* @param outlen Length of output in bytes
|
790 | 793 |
* @return CRYPT_OK on success
|
791 | 794 |
*/
|
792 | 795 |
int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen)
|
|
800 | 803 |
|
801 | 804 |
/*
|
802 | 805 |
* Terminate and clear Sosemanuk key context
|
803 | |
* @param kc The Sosemanuk key context
|
|
806 |
* @param ss The Sosemanuk state
|
804 | 807 |
* @return CRYPT_OK on success
|
805 | 808 |
*/
|
806 | 809 |
int sosemanuk_done(sosemanuk_state *ss)
|