2 * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Neither the name of author nor the names of its contributors may
10 * be used to endorse or promote products derived from this software
11 * without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #ifndef OPENSSL_NO_SEED
35 # include <openssl/seed.h>
36 # include "seed_locl.h"
38 static seed_word SS[4][256] = { {
39 0x2989a1a8, 0x05858184, 0x16c6d2d4,
40 0x13c3d3d0, 0x14445054, 0x1d0d111c,
41 0x2c8ca0ac, 0x25052124,
42 0x1d4d515c, 0x03434340, 0x18081018,
43 0x1e0e121c, 0x11415150, 0x3cccf0fc,
44 0x0acac2c8, 0x23436360,
45 0x28082028, 0x04444044, 0x20002020,
46 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0,
47 0x08c8c0c8, 0x17071314,
48 0x2585a1a4, 0x0f8f838c, 0x03030300,
49 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
50 0x12c2d2d0, 0x2ecee2ec,
51 0x30407070, 0x0c8c808c, 0x3f0f333c,
52 0x2888a0a8, 0x32023230, 0x1dcdd1dc,
53 0x36c6f2f4, 0x34447074,
54 0x2ccce0ec, 0x15859194, 0x0b0b0308,
55 0x17475354, 0x1c4c505c, 0x1b4b5358,
56 0x3d8db1bc, 0x01010100,
57 0x24042024, 0x1c0c101c, 0x33437370,
58 0x18889098, 0x10001010, 0x0cccc0cc,
59 0x32c2f2f0, 0x19c9d1d8,
60 0x2c0c202c, 0x27c7e3e4, 0x32427270,
61 0x03838380, 0x1b8b9398, 0x11c1d1d0,
62 0x06868284, 0x09c9c1c8,
63 0x20406060, 0x10405050, 0x2383a3a0,
64 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4,
65 0x1e8e929c, 0x0f4f434c,
66 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4,
67 0x38487078, 0x2686a2a4, 0x12021210,
68 0x2f8fa3ac, 0x15c5d1d4,
69 0x21416160, 0x03c3c3c0, 0x3484b0b4,
70 0x01414140, 0x12425250, 0x3d4d717c,
71 0x0d8d818c, 0x08080008,
72 0x1f0f131c, 0x19899198, 0x00000000,
73 0x19091118, 0x04040004, 0x13435350,
74 0x37c7f3f4, 0x21c1e1e0,
75 0x3dcdf1fc, 0x36467274, 0x2f0f232c,
76 0x27072324, 0x3080b0b0, 0x0b8b8388,
77 0x0e0e020c, 0x2b8ba3a8,
78 0x2282a2a0, 0x2e4e626c, 0x13839390,
79 0x0d4d414c, 0x29496168, 0x3c4c707c,
80 0x09090108, 0x0a0a0208,
81 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0,
82 0x05c5c1c4, 0x07878384, 0x14041014,
83 0x3ecef2fc, 0x24446064,
84 0x1eced2dc, 0x2e0e222c, 0x0b4b4348,
85 0x1a0a1218, 0x06060204, 0x21012120,
86 0x2b4b6368, 0x26466264,
87 0x02020200, 0x35c5f1f4, 0x12829290,
88 0x0a8a8288, 0x0c0c000c, 0x3383b3b0,
89 0x3e4e727c, 0x10c0d0d0,
90 0x3a4a7278, 0x07474344, 0x16869294,
91 0x25c5e1e4, 0x26062224, 0x00808080,
92 0x2d8da1ac, 0x1fcfd3dc,
93 0x2181a1a0, 0x30003030, 0x37073334,
94 0x2e8ea2ac, 0x36063234, 0x15051114,
95 0x22022220, 0x38083038,
96 0x34c4f0f4, 0x2787a3a4, 0x05454144,
97 0x0c4c404c, 0x01818180, 0x29c9e1e8,
98 0x04848084, 0x17879394,
99 0x35053134, 0x0bcbc3c8, 0x0ecec2cc,
100 0x3c0c303c, 0x31417170, 0x11011110,
101 0x07c7c3c4, 0x09898188,
102 0x35457174, 0x3bcbf3f8, 0x1acad2d8,
103 0x38c8f0f8, 0x14849094, 0x19495158,
104 0x02828280, 0x04c4c0c4,
105 0x3fcff3fc, 0x09494148, 0x39093138,
106 0x27476364, 0x00c0c0c0, 0x0fcfc3cc,
107 0x17c7d3d4, 0x3888b0b8,
108 0x0f0f030c, 0x0e8e828c, 0x02424240,
109 0x23032320, 0x11819190, 0x2c4c606c,
110 0x1bcbd3d8, 0x2484a0a4,
111 0x34043034, 0x31c1f1f0, 0x08484048,
112 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
113 0x2d0d212c, 0x00404040,
114 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc,
115 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8,
116 0x0e4e424c, 0x15455154,
117 0x3b0b3338, 0x1cccd0dc, 0x28486068,
118 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8,
119 0x0a4a4248, 0x16465254,
120 0x37477374, 0x2080a0a0, 0x2dcde1ec,
121 0x06464244, 0x3585b1b4, 0x2b0b2328,
122 0x25456164, 0x3acaf2f8,
123 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0,
124 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8,
125 0x26c6e2e4, 0x3282b2b0,
126 0x31013130, 0x2acae2e8, 0x2d4d616c,
127 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0,
128 0x0dcdc1cc, 0x08888088,
129 0x16061214, 0x3a0a3238, 0x18485058,
130 0x14c4d0d4, 0x22426260, 0x29092128,
131 0x07070304, 0x33033330,
132 0x28c8e0e8, 0x1b0b1318, 0x05050104,
133 0x39497178, 0x10809090, 0x2a4a6268,
134 0x2a0a2228, 0x1a8a9298}, {
648 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
649 0x83b3b033, 0x88b0b838,
650 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f,
651 0x4b63682b, 0x4b53581b,
652 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020,
653 0xc2e2e022, 0x87a3a427,
654 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
655 0x06323436, 0x4b43480b,
656 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404,
657 0x06121416, 0xc4f0f434,
658 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d,
659 0x8e828c0e, 0x88909818,
660 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
661 0x0d010c0d, 0xcfd3dc1f,
662 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f,
663 0xc1f1f031, 0x42727032,
664 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427,
665 0x8ca0ac2c, 0x8b83880b,
666 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
667 0x8aa2a82a, 0x04303434,
668 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414,
669 0x08101818, 0xc8f0f838,
670 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d,
671 0x86828406, 0x89b1b839,
672 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
673 0x4a62682a, 0x81b1b031,
674 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404,
675 0x48606828, 0x41717031,
676 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e,
677 0xc6e2e426, 0x49515819,
678 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
679 0x8ba3a82b, 0xc0d0d010,
680 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c,
681 0x8d818c0d, 0x8fb3bc3f,
682 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023,
683 0x03232023, 0x4d414c0d,
684 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
685 0x8ab2b83a, 0x4e626c2e,
686 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809,
687 0x48707838, 0xccc0cc0c,
688 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435,
689 0x00101010, 0x03030003,
690 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
691 0xcae2e82a, 0x09010809,
692 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020,
693 0x8db1bc3d, 0x05010405,
694 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829,
695 0x46525416, 0x43434003,
696 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
697 0x48404808, 0x49717839,
698 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c,
699 0x0b13181b, 0x4f535c1f,
700 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f,
701 0x00000000, 0x46424406,
702 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
703 0xc9c1c809, 0xcdf1fc3d,
704 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424,
705 0x8bb3b83b, 0x4c707c3c,
706 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404,
707 0x49616829, 0x83939013,
708 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
709 0x0a02080a, 0x87838407,
710 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b,
711 0x4a42480a, 0x87b3b437}
714 /* key schedule constants - golden ratio */
715 # define KC0 0x9e3779b9
716 # define KC1 0x3c6ef373
717 # define KC2 0x78dde6e6
718 # define KC3 0xf1bbcdcc
719 # define KC4 0xe3779b99
720 # define KC5 0xc6ef3733
721 # define KC6 0x8dde6e67
722 # define KC7 0x1bbcdccf
723 # define KC8 0x3779b99e
724 # define KC9 0x6ef3733c
725 # define KC10 0xdde6e678
726 # define KC11 0xbbcdccf1
727 # define KC12 0x779b99e3
728 # define KC13 0xef3733c6
729 # define KC14 0xde6e678d
730 # define KC15 0xbcdccf1b
732 void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
733 SEED_KEY_SCHEDULE *ks)
735 seed_word x1, x2, x3, x4;
738 char2word(rawkey, x1);
739 char2word(rawkey + 4, x2);
740 char2word(rawkey + 8, x3);
741 char2word(rawkey + 12, x4);
743 t0 = (x1 + x3 - KC0) & 0xffffffff;
744 t1 = (x2 - x4 + KC0) & 0xffffffff;
745 KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
746 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);
747 KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
748 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);
749 KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
750 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);
751 KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
752 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);
753 KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
754 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);
755 KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
756 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);
757 KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
758 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);
759 KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
760 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);
761 KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
762 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);
763 KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
764 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);
765 KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
766 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);
767 KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
768 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);
769 KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
770 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);
771 KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
772 KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);
773 KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
774 KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);
775 KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
778 void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
779 unsigned char d[SEED_BLOCK_SIZE],
780 const SEED_KEY_SCHEDULE *ks)
782 seed_word x1, x2, x3, x4;
786 char2word(s + 4, x2);
787 char2word(s + 8, x3);
788 char2word(s + 12, x4);
790 E_SEED(t0, t1, x1, x2, x3, x4, 0);
791 E_SEED(t0, t1, x3, x4, x1, x2, 2);
792 E_SEED(t0, t1, x1, x2, x3, x4, 4);
793 E_SEED(t0, t1, x3, x4, x1, x2, 6);
794 E_SEED(t0, t1, x1, x2, x3, x4, 8);
795 E_SEED(t0, t1, x3, x4, x1, x2, 10);
796 E_SEED(t0, t1, x1, x2, x3, x4, 12);
797 E_SEED(t0, t1, x3, x4, x1, x2, 14);
798 E_SEED(t0, t1, x1, x2, x3, x4, 16);
799 E_SEED(t0, t1, x3, x4, x1, x2, 18);
800 E_SEED(t0, t1, x1, x2, x3, x4, 20);
801 E_SEED(t0, t1, x3, x4, x1, x2, 22);
802 E_SEED(t0, t1, x1, x2, x3, x4, 24);
803 E_SEED(t0, t1, x3, x4, x1, x2, 26);
804 E_SEED(t0, t1, x1, x2, x3, x4, 28);
805 E_SEED(t0, t1, x3, x4, x1, x2, 30);
808 word2char(x4, d + 4);
809 word2char(x1, d + 8);
810 word2char(x2, d + 12);
813 void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
814 unsigned char d[SEED_BLOCK_SIZE],
815 const SEED_KEY_SCHEDULE *ks)
817 seed_word x1, x2, x3, x4;
821 char2word(s + 4, x2);
822 char2word(s + 8, x3);
823 char2word(s + 12, x4);
825 E_SEED(t0, t1, x1, x2, x3, x4, 30);
826 E_SEED(t0, t1, x3, x4, x1, x2, 28);
827 E_SEED(t0, t1, x1, x2, x3, x4, 26);
828 E_SEED(t0, t1, x3, x4, x1, x2, 24);
829 E_SEED(t0, t1, x1, x2, x3, x4, 22);
830 E_SEED(t0, t1, x3, x4, x1, x2, 20);
831 E_SEED(t0, t1, x1, x2, x3, x4, 18);
832 E_SEED(t0, t1, x3, x4, x1, x2, 16);
833 E_SEED(t0, t1, x1, x2, x3, x4, 14);
834 E_SEED(t0, t1, x3, x4, x1, x2, 12);
835 E_SEED(t0, t1, x1, x2, x3, x4, 10);
836 E_SEED(t0, t1, x3, x4, x1, x2, 8);
837 E_SEED(t0, t1, x1, x2, x3, x4, 6);
838 E_SEED(t0, t1, x3, x4, x1, x2, 4);
839 E_SEED(t0, t1, x1, x2, x3, x4, 2);
840 E_SEED(t0, t1, x3, x4, x1, x2, 0);
843 word2char(x4, d + 4);
844 word2char(x1, d + 8);
845 word2char(x2, d + 12);
848 #endif /* OPENSSL_NO_SEED */