Codebase list libcryptx-perl / 29ea1dc
ltc sync - sosemanuk Karel Miko 6 years ago
1 changed file(s) with 66 addition(s) and 72 deletion(s). Raw diff Collapse all Expand all
195195 /*
196196 * Key schedule: initialize the key context structure with the provided
197197 * secret key. The secret key is an array of 1 to 32 bytes.
198 * @param kc The Sosemanuk key context
198 * @param ss The Sosemanuk state
199199 * @param key Key
200 * @param key_len Length of key
200 * @param keylen Length of key
201201 * @return CRYPT_OK on success
202202 */
203 int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long key_len)
203 int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long keylen)
204204 {
205205 /*
206206 * This key schedule is actually a truncated Serpent key schedule.
254254 ulong32 w0, w1, w2, w3, w4, w5, w6, w7;
255255 int i = 0;
256256
257 LTC_ARGCHK(ss != NULL);
258 LTC_ARGCHK(key != NULL);
259
260 /*
261 * Initialize the pointer to 666 as a flag that can be checked
262 * by sosemanuk_crypt() as an indication sosemanuk_setiv() was
263 * not called. (sosemanuk_setiv() will set the pointer to a
264 * more reasonable value.)
265 */
266 ss->ptr = 666;
267
257268 /*
258269 * The key is copied into the wbuf[] buffer and padded to 256 bits
259270 * as described in the Serpent specification.
260271 */
261 if (key_len == 0 || key_len > 32) {
272 if (keylen == 0 || keylen > 32) {
262273 fprintf(stderr, "invalid key size: %lu\n",
263 (unsigned long)key_len);
274 (unsigned long)keylen);
264275 exit(EXIT_FAILURE);
265276 }
266 XMEMCPY(wbuf, key, key_len);
267 if (key_len < 32) {
268 wbuf[key_len] = 0x01;
269 if (key_len < 31)
270 XMEMSET(wbuf + key_len + 1, 0, 31 - key_len);
277 XMEMCPY(wbuf, key, keylen);
278 if (keylen < 32) {
279 wbuf[keylen] = 0x01;
280 if (keylen < 31)
281 XMEMSET(wbuf + keylen + 1, 0, 31 - keylen);
271282 }
272283
273284 LOAD32L(w0, wbuf);
325336 /*
326337 * Cipher initialization: the cipher internal state is initialized, using
327338 * the provided key context and IV. The IV length is up to 16 bytes. If
328 * "iv_len" is 0 (no IV), then the "iv" parameter can be NULL.
329 * @param rc The Sosemanuk run context
330 * @param kc The Sosemanuk key context
339 * "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.
340 * @param ss The Sosemanuk state
331341 * @param iv Initialization vector
332 * @param iv_len Length of iv
342 * @param ivlen Length of iv
333343 * @return CRYPT_OK on success
334344 */
335 int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long iv_len)
345 int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
336346 {
337347
338348 /*
370380 } while (0)
371381
372382 ulong32 r0, r1, r2, r3, r4;
373 unsigned char ivtmp[16];
374
375 if (iv_len >= sizeof ivtmp) {
376 XMEMCPY(ivtmp, iv, sizeof ivtmp);
377 } else {
378 if (iv_len > 0)
379 XMEMCPY(ivtmp, iv, iv_len);
380 XMEMSET(ivtmp + iv_len, 0, (sizeof ivtmp) - iv_len);
381 }
383 unsigned char ivtmp[16] = {0};
384
385 LTC_ARGCHK(ss != NULL);
386 LTC_ARGCHK(ivlen >= 0 && ivlen <= 16);
387 LTC_ARGCHK(iv != NULL || ivlen == 0);
388
389 if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
382390
383391 /*
384392 * Decode IV into four 32-bit words (little-endian).
431439 ss->s01 = r2;
432440 ss->s00 = r3;
433441
434 ss->ptr = sizeof ss->buf;
442 ss->ptr = sizeof(ss->buf);
435443
436444 #undef KA
437445 #undef FSS
719727
720728 /*
721729 * Combine buffers in1[] and in2[] by XOR, result in out[]. The length
722 * is "data_len" (in bytes). Partial overlap of out[] with either in1[]
730 * is "datalen" (in bytes). Partial overlap of out[] with either in1[]
723731 * or in2[] is not allowed. Total overlap (out == in1 and/or out == in2)
724732 * is allowed.
725733 */
726734 static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in2,
727 unsigned char *out, unsigned long data_len)
735 unsigned char *out, unsigned long datalen)
728736 {
729 while (data_len -- > 0)
737 while (datalen -- > 0)
730738 *out ++ = *in1 ++ ^ *in2 ++;
731739 }
732740
736744 * buffer, combined by XOR with the stream, and the result is written
737745 * in the "out" buffer. "in" and "out" must be either equal, or
738746 * reference distinct buffers (no partial overlap is allowed).
739 * @param rc The Sosemanuk run context
747 * @param ss The Sosemanuk state
740748 * @param in Data in
741749 * @param out Data out
742 * @param data_len Length of data
750 * @param datalen Length of data
743751 * @return CRYPT_OK on success
744752 */
745753 int sosemanuk_crypt(sosemanuk_state *ss,
746 const unsigned char *in, unsigned long data_len, unsigned char *out)
754 const unsigned char *in, unsigned long datalen, unsigned char *out)
747755 {
748 if (ss->ptr < (sizeof ss->buf)) {
749 unsigned long rlen = (sizeof ss->buf) - ss->ptr;
750
751 if (rlen > data_len)
752 rlen = data_len;
756 LTC_ARGCHK(ss != NULL);
757 LTC_ARGCHK(in != NULL);
758 LTC_ARGCHK(out != NULL);
759 LTC_ARGCHK(ss->ptr != 666); /* check whether sosemanuk_setiv was called */
760
761 if (ss->ptr < (sizeof(ss->buf))) {
762 unsigned long rlen = (sizeof(ss->buf)) - ss->ptr;
763
764 if (rlen > datalen)
765 rlen = datalen;
753766 _xorbuf(ss->buf + ss->ptr, in, out, rlen);
754767 in += rlen;
755768 out += rlen;
756 data_len -= rlen;
769 datalen -= rlen;
757770 ss->ptr += rlen;
758771 }
759 while (data_len > 0) {
772 while (datalen > 0) {
760773 _sosemanuk_internal(ss);
761 if (data_len >= sizeof ss->buf) {
762 _xorbuf(ss->buf, in, out, sizeof ss->buf);
763 in += sizeof ss->buf;
764 out += sizeof ss->buf;
765 data_len -= sizeof ss->buf;
774 if (datalen >= sizeof(ss->buf)) {
775 _xorbuf(ss->buf, in, out, sizeof(ss->buf));
776 in += sizeof(ss->buf);
777 out += sizeof(ss->buf);
778 datalen -= sizeof(ss->buf);
766779 } else {
767 _xorbuf(ss->buf, in, out, data_len);
768 ss->ptr = data_len;
769 data_len = 0;
780 _xorbuf(ss->buf, in, out, datalen);
781 ss->ptr = datalen;
782 datalen = 0;
770783 }
771784 }
772785 return CRYPT_OK;
776789 /*
777790 * Cipher operation, as a PRNG: the provided output buffer is filled with
778791 * pseudo-random bytes as output from the stream cipher.
779 * @param rc The Sosemanuk run context
792 * @param ss The Sosemanuk state
780793 * @param out Data out
781 * @param out_len Length of output
794 * @param outlen Length of output
782795 * @return CRYPT_OK on success
783796 */
784 int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long out_len)
797 int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen)
785798 {
786 if (ss->ptr < (sizeof ss->buf)) {
787 unsigned long rlen = (sizeof ss->buf) - ss->ptr;
788
789 if (rlen > out_len)
790 rlen = out_len;
791 XMEMCPY(out, ss->buf + ss->ptr, rlen);
792 out += rlen;
793 out_len -= rlen;
794 ss->ptr += rlen;
795 }
796 while (out_len > 0) {
797 _sosemanuk_internal(ss);
798 if (out_len >= sizeof ss->buf) {
799 XMEMCPY(out, ss->buf, sizeof ss->buf);
800 out += sizeof ss->buf;
801 out_len -= sizeof ss->buf;
802 } else {
803 XMEMCPY(out, ss->buf, out_len);
804 ss->ptr = out_len;
805 out_len = 0;
806 }
807 }
808 return CRYPT_OK;
799 if (outlen == 0) return CRYPT_OK; /* nothing to do */
800 LTC_ARGCHK(out != NULL);
801 XMEMSET(out, 0, outlen);
802 return sosemanuk_crypt(ss, out, outlen, out);
809803 }
810804
811805