Annotation of OpenXM_contrib2/asir2000/io/des.c, Revision 1.6
1.6 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/io/des.c,v 1.5 2000/12/05 09:06:03 noro Exp $ */
1.1 noro 2: /* Copyright (C) 1996 S.Amada */
3:
4: #include <stdio.h>
5: #include <stdlib.h>
1.6 ! noro 6: #include <string.h>
1.1 noro 7:
8: #define ROUND 16 /* 段数 */
9:
10: typedef unsigned long ULONG;
11: typedef unsigned short USHORT;
12: typedef unsigned char UCHAR;
13:
14:
15: /* 関数のproto type */
16: void des_enc(ULONG *, UCHAR *, ULONG *);
17: ULONG round_func(ULONG , UCHAR *);
18: ULONG s_box_func(UCHAR *);
19: void des_dec(ULONG *, UCHAR *, ULONG *);
1.6 ! noro 20: void key_schedule(UCHAR *,UCHAR *);
1.1 noro 21:
22: /* 鍵の縮約型転置 PC-1 */
23: static USHORT pc_1[56] = {
24: 56, 48, 40, 32, 24, 16, 8,
25: 0, 57, 49, 41, 33, 25, 17,
26: 9, 1, 58, 50, 42, 34, 26,
27: 18, 10, 2, 59, 51, 43, 35,
28: 62, 54, 46, 38, 30, 22, 14,
29: 6, 61, 53, 45, 37, 29, 21,
30: 13, 5, 60, 52, 44, 36, 28,
31: 20, 12, 4, 27, 19, 11, 3
32: };
33:
34: /* 鍵のシフト回数 */
35: static USHORT k_rot[16] = {
36: 1, 2, 4, 6, 8, 10, 12, 14,
37: 15, 17, 19, 21, 23, 25, 27, 28
38: };
39:
40: /* 鍵の縮約型転置 PC-2 */
41: static USHORT pc_2[48] = {
42: 13, 16, 10, 23, 0, 4,
43: 2, 27, 14, 5, 20, 9,
44: 22, 18, 11, 3, 25, 7,
45: 15, 6, 26, 19, 12, 1,
46: 40, 51, 30, 36, 46, 54,
47: 29, 39, 50, 44, 32, 47,
48: 43, 48, 38, 55, 33, 52,
49: 45, 41, 49, 35, 28, 31
50: };
51:
52: /* 初期転置(IP) */
53: static USHORT ip_1[64] = {
54: 57, 49, 41, 33, 25, 17, 9, 1,
55: 59, 51, 43, 35, 27, 19, 11, 3,
56: 61, 53, 45, 37, 29, 21, 13, 5,
57: 63, 55, 47, 39, 31, 23, 15, 7,
58: 56, 48, 40, 32, 24, 16, 8, 0,
59: 58, 50, 42, 34, 26, 18, 10, 2,
60: 60, 52, 44, 36, 28, 20, 12, 4,
61: 62, 54, 46, 38, 30, 22, 14, 6
62: };
63:
64: /* 初期転置(IP^-1) */
65: static USHORT ip_2[64] = {
66: 39, 7, 47, 15, 55, 23, 63, 31,
67: 38, 6, 46, 14, 54, 22, 62, 30,
68: 37, 5, 45, 13, 53, 21, 61, 29,
69: 36, 4, 44, 12, 52, 20, 60, 28,
70: 35, 3, 43, 11, 51, 19, 59, 27,
71: 34, 2, 42, 10, 50, 18, 58, 26,
72: 33, 1, 41, 9, 49, 17, 57, 25,
73: 32, 0, 40, 8, 48, 16, 56, 24
74: };
75:
76: /* 拡大転置(E) */
77: static USHORT f_expand[48] = {
78: 31, 0, 1, 2, 3, 4,
79: 3, 4, 5, 6, 7, 8,
80: 7, 8, 9, 10, 11, 12,
81: 11, 12, 13, 14, 15, 16,
82: 15, 16, 17, 18, 19, 20,
83: 19, 20, 21, 22, 23, 24,
84: 23, 24, 25, 26, 27, 28,
85: 27, 28, 29, 30, 31, 0
86: };
87:
88: /* S-box */
89: static USHORT s_1[64] = {
90: 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
91: 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
92: 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
93: 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
94: };
95:
96: static USHORT s_2[64] = {
97: 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
98: 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
99: 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
100: 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
101: };
102:
103: static USHORT s_3[64] = {
104: 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
105: 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
106: 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
107: 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
108: };
109:
110: static USHORT s_4[64] = {
111: 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
112: 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
113: 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
114: 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
115: };
116:
117: static USHORT s_5[64] = {
118: 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
119: 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
120: 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
121: 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
122: };
123:
124: static USHORT s_6[64] = {
125: 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
126: 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
127: 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
128: 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
129: };
130:
131: static USHORT s_7[64] = {
132: 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
133: 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
134: 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
135: 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
136: };
137:
138: static USHORT s_8[64] = {
139: 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
140: 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
141: 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
142: 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
143: };
144:
145: /* 転置(P) */
146: static USHORT f_perm[32] = {
147: 15, 6, 19, 20,
148: 28, 11, 27, 16,
149: 0, 14, 22, 25,
150: 4, 17, 30, 9,
151: 1, 7, 23, 13,
152: 31, 26, 2, 8,
153: 18, 12, 29, 5,
154: 21, 10, 3, 24
155: };
156:
157:
158: /****************************************************************************
159: * *
160: * 暗号化関数 *
161: * void des_enc(plane,r_key,cipher) *
162: * ULONG *plane : 平文(64 bit) (input) *
163: * UCHAR *r_key : 拡大鍵(48 * 16 bit) (input) *
164: * ULONG *cipher : 暗号文(64 bit) (output) *
165: * *
166: * 機能 : 平文及び拡大鍵を入力とし、DESのアルゴリズムに基づき暗号文 *
167: * を生成する。 *
168: * 戻り値 : なし *
169: * *
170: ****************************************************************************/
171: void des_enc(plane,r_key,cipher)
172: ULONG *plane; /* 平文(64 bit) */
173: UCHAR *r_key; /* 拡大鍵(48 * 16 bit) */
174: ULONG *cipher; /* 暗号文(64 bit) */
175: {
176: ULONG l_text,r_text,
1.6 ! noro 177: l_work,r_work,tmp_text;
1.1 noro 178: int loop;
179:
180:
181: l_text = *plane;
182: r_text = *(plane+1);
183:
184: /* 初期転置(IP) */
185: l_work = 0x00000000L;
186: r_work = 0x00000000L;
187: for(loop = 0;loop < 64;loop++)
188: {
189: if(loop < 32)
190: {
191: if(ip_1[loop] < 32)
192: {
193: if(l_text & (0x80000000L >> ip_1[loop]))
194: l_work |= 0x80000000L >> loop;
195: }
196: else
197: {
198: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
199: l_work |= 0x80000000L >> loop;
200: }
201: }
202: else
203: {
204: if(ip_1[loop] < 32)
205: {
206: if(l_text & (0x80000000L >> ip_1[loop]))
207: r_work |= 0x80000000L >> (loop - 32);
208: }
209: else
210: {
211: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
212: r_work |= 0x80000000L >> (loop - 32);
213: }
214: }
215: }
216: l_text = l_work;
217: r_text = r_work;
218:
219: #ifdef DEBUG
220: printf("l_text: %08x,r_text: %08x.\n",l_text,r_text);
221: #endif
222:
223: /* 段関数 f(R,K) */
224: for(loop = 0;loop < ROUND;loop++,r_key+=6)
225: {
226: tmp_text = l_text;
227: l_text = r_text;
228: r_text = (ULONG)tmp_text ^ (ULONG)round_func(r_text,r_key);
229: #ifdef DEBUG
230: printf("round[%d] l_text: %08x, r_text: %08x.\n",loop,l_text,r_text);
231: #endif
232: }
233: tmp_text = l_text;
234: l_text = r_text;
235: r_text = tmp_text;
236:
237: /* 最終転置(IP^-1) */
238: l_work = 0x00000000L;
239: r_work = 0x00000000L;
240: for(loop = 0;loop < 64;loop++)
241: {
242: if(loop < 32)
243: {
244: if(ip_2[loop] < 32)
245: {
246: if(l_text & (0x80000000L >> ip_2[loop]))
247: l_work |= 0x80000000L >> loop;
248: }
249: else
250: {
251: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
252: l_work |= 0x80000000L >> loop;
253: }
254: }
255: else
256: {
257: if(ip_2[loop] < 32)
258: {
259: if(l_text & (0x80000000L >> ip_2[loop]))
260: r_work |= 0x80000000L >> (loop - 32);
261: }
262: else
263: {
264: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
265: r_work |= 0x80000000L >> (loop - 32);
266: }
267: }
268: }
269: /*l_text = l_work;
270: r_text = r_work;*/
271:
272: #ifdef DEBUG
273: printf("l_text: %08x,r_text: %08x.\n",l_text,r_text);
274: #endif
275:
276: *cipher = l_work;
277: *(cipher+1) = r_work;
278:
279: return;
280: }
281:
282:
283: /****************************************************************************
284: * *
285: * 段関数(f(R,K) *
286: * ULONG round_func(text,key) *
287: * ULONG text : 入力文(32 bit) (input) *
288: * UCHAR *key : 拡大鍵(48 bit) (input) *
289: * *
290: * 機能 : 入力文及び拡大鍵を入力とし、DESの段関数の出力を返す。 *
291: * 戻り値 : 段関数(f(R,K))の出力値 *
292: * *
293: ****************************************************************************/
294: ULONG round_func(text,key)
295: ULONG text;
296: UCHAR *key;
297: {
298: UCHAR e_val[6],k_work[6];
299: ULONG t_work,t_val;
300: int loop;
301:
302:
303: t_work = text;
304:
305: /* 拡大転置(E) 32bit(4byte) -> 48bit(6byte) */
306: memset(e_val,0x00L,6);
307: for(loop = 0;loop < 48;loop++)
308: if(t_work & (0x80000000L >> f_expand[loop]))
309: e_val[loop / 8] |= 0x80L >> (loop % 8);
310:
311: #ifdef DEBUG
312: printf("Expand: %02x%02x%02x%02x%02x%02x.\n",
313: e_val[0],e_val[1],e_val[2],e_val[3],e_val[4],e_val[5]);
314: #endif
315:
316: /* 鍵との排他的論理和演算 48bit(6byte) -> 48bit(6byte) */
317: memset(k_work,0x00L,6);
318: for(loop = 0;loop < 6;loop++,key++)
319: k_work[loop] = e_val[loop] ^ *key;
320:
321: #ifdef DEBUG
322: printf("Key EXORed: %02x%02x%02x%02x%02x%02x.\n",
323: k_work[0],k_work[1],k_work[2],k_work[3],k_work[4],k_work[5]);
324: #endif
325:
326: /* S-box 48bit(6byte) -> 32bit(4byte) */
327: t_work = s_box_func(k_work);
328:
329: #ifdef DEBUG
330: printf("s-box value: %08x.\n",t_work);
331: #endif
332:
333: /* 転置(P) 32bit(4byte) -> 32bit(4byte) */
334: t_val = 0x00000000L;
335: for(loop = 0;loop < 32;loop++)
336: if(t_work & (0x80000000L >> f_perm[loop]))
337: t_val |= 0x80000000L >> loop;
338:
339: #ifdef DEBUG
340: printf("Round func value: %08x.\n",t_val);
341: #endif
342:
343: return(t_val);
344: }
345:
346:
347: /****************************************************************************
348: * *
349: * 段関数(f(R,K) *
350: * ULONG s_box_func(i_data) *
351: * UCHAR *i_data : 入力文(48 bit) (input) *
352: * *
353: * 機能 : 入力文を入力とし、DESのS-Boxの出力値(32 bit)を返す。 *
354: * 戻り値 : S-Boxの出力値 *
355: * *
356: ****************************************************************************/
357: ULONG s_box_func(i_data)
358: UCHAR *i_data;
359: {
360: int loop;
361: UCHAR work[6],s_work[8],val;
362: ULONG fval;
363:
364:
365: for(loop = 0;loop < 6;loop++,i_data++) work[loop] = *i_data;
366:
367: /* S1 */
1.6 ! noro 368: s_work[0] = (work[0] >> 2) & 0x3f;
! 369: val = (s_work[0] >> 1) & 0x0f;
1.1 noro 370: if(s_work[0] & 0x20L)
371: {
1.6 ! noro 372: if(s_work[0] & 0x01L) s_work[0] = (UCHAR)s_1[val+48];
! 373: else s_work[0] = (UCHAR)s_1[val+32];
1.1 noro 374: }
375: else
376: {
1.6 ! noro 377: if(s_work[0] & 0x01L) s_work[0] = (UCHAR)s_1[val+16];
! 378: else s_work[0] = (UCHAR)s_1[val];
1.1 noro 379: }
380:
381: /* S2 */
1.6 ! noro 382: s_work[1] = ((work[0] << 4) | (work[1] >> 4)) & 0x3f;
! 383: val = (s_work[1] >> 1) & 0x0f;
1.1 noro 384: if(s_work[1] & 0x20L)
385: {
1.6 ! noro 386: if(s_work[1] & 0x01L) s_work[1] = (UCHAR)s_2[val+48];
! 387: else s_work[1] = (UCHAR)s_2[val+32];
1.1 noro 388: }
389: else
390: {
1.6 ! noro 391: if(s_work[1] & 0x01L) s_work[1] = (UCHAR)s_2[val+16];
! 392: else s_work[1] = (UCHAR)s_2[val];
1.1 noro 393: }
394:
395: /* S3 */
1.6 ! noro 396: s_work[2] = ((work[1] << 2) | (work[2] >> 6)) & 0x3f;
! 397: val = (s_work[2] >> 1) & 0x0f;
1.1 noro 398: if(s_work[2] & 0x20L)
399: {
1.6 ! noro 400: if(s_work[2] & 0x01L) s_work[2] = (UCHAR)s_3[val+48];
! 401: else s_work[2] = (UCHAR)s_3[val+32];
1.1 noro 402: }
403: else
404: {
1.6 ! noro 405: if(s_work[2] & 0x01L) s_work[2] = (UCHAR)s_3[val+16];
! 406: else s_work[2] = (UCHAR)s_3[val];
1.1 noro 407: }
408:
409: /* S4 */
1.6 ! noro 410: s_work[3] = work[2] & 0x3f;
! 411: val = (s_work[3] >> 1) & 0x0f;
1.1 noro 412: if(s_work[3] & 0x20L)
413: {
1.6 ! noro 414: if(s_work[3] & 0x01L) s_work[3] = (UCHAR)s_4[val+48];
! 415: else s_work[3] = (UCHAR)s_4[val+32];
1.1 noro 416: }
417: else
418: {
1.6 ! noro 419: if(s_work[3] & 0x01L) s_work[3] = (UCHAR)s_4[val+16];
! 420: else s_work[3] = (UCHAR)s_4[val];
1.1 noro 421: }
422:
423: /* S5 */
1.6 ! noro 424: s_work[4] = (work[3] >> 2) & 0x3f;
! 425: val = (s_work[4] >> 1) & 0x0f;
1.1 noro 426: if(s_work[4] & 0x20L)
427: {
1.6 ! noro 428: if(s_work[4] & 0x01L) s_work[4] = (UCHAR)s_5[val+48];
! 429: else s_work[4] = (UCHAR)s_5[val+32];
1.1 noro 430: }
431: else
432: {
1.6 ! noro 433: if(s_work[4] & 0x01L) s_work[4] = (UCHAR)s_5[val+16];
! 434: else s_work[4] = (UCHAR)s_5[val];
1.1 noro 435: }
436:
437: /* S6 */
1.6 ! noro 438: s_work[5] = ((work[3] << 4) | (work[4] >> 4)) & 0x3f;
! 439: val = (s_work[5] >> 1) & 0x0f;
1.1 noro 440: if(s_work[5] & 0x20L)
441: {
1.6 ! noro 442: if(s_work[5] & 0x01L) s_work[5] = (UCHAR)s_6[val+48];
! 443: else s_work[5] = (UCHAR)s_6[val+32];
1.1 noro 444: }
445: else
446: {
1.6 ! noro 447: if(s_work[5] & 0x01L) s_work[5] = (UCHAR)s_6[val+16];
! 448: else s_work[5] = (UCHAR)s_6[val];
1.1 noro 449: }
450:
451: /* S7 */
1.6 ! noro 452: s_work[6] = ((work[4] << 2) | (work[5] >> 6)) & 0x3f;
! 453: val = (s_work[6] >> 1) & 0x0f;
1.1 noro 454: if(s_work[6] & 0x20L)
455: {
1.6 ! noro 456: if(s_work[6] & 0x01L) s_work[6] = (UCHAR)s_7[val+48];
! 457: else s_work[6] = (UCHAR)s_7[val+32];
1.1 noro 458: }
459: else
460: {
1.6 ! noro 461: if(s_work[6] & 0x01L) s_work[6] = (UCHAR)s_7[val+16];
! 462: else s_work[6] = (UCHAR)s_7[val];
1.1 noro 463: }
464:
465: /* S8 */
1.6 ! noro 466: s_work[7] = work[5] & 0x3f;
! 467: val = (s_work[7] >> 1) & 0x0f;
1.1 noro 468: if(s_work[7] & 0x20L)
469: {
1.6 ! noro 470: if(s_work[7] & 0x01L) s_work[7] = (UCHAR)s_8[val+48];
! 471: else s_work[7] = (UCHAR)s_8[val+32];
1.1 noro 472: }
473: else
474: {
1.6 ! noro 475: if(s_work[7] & 0x01L) s_work[7] = (UCHAR)s_8[val+16];
! 476: else s_work[7] = (UCHAR)s_8[val];
1.1 noro 477: }
478:
479: fval = (s_work[0] << 28) | (s_work[1] << 24)
480: | (s_work[2] << 20) | (s_work[3] << 16)
481: | (s_work[4] << 12) | (s_work[5] << 8)
482: | (s_work[6] << 4) | s_work[7];
483:
484: return(fval);
485: }
486:
487:
488: /****************************************************************************
489: * *
490: * 復号関数 *
491: * void des_dec(cipher,r_key,plane) *
492: * ULONG *cipher : 暗号文(64 bit) (output) *
493: * UCHAR *r_key : 拡大鍵(48 * 16 bit) (input) *
494: * ULONG *plane : 平文(64 bit) (input) *
495: * *
496: * 機能 : 暗号文及び拡大鍵を入力とし、DESのアルゴリズムに基づき平文 *
497: * を生成する。 *
498: * 戻り値 : なし *
499: * *
500: ****************************************************************************/
501: void des_dec(cipher,r_key,plane)
502: ULONG *cipher;
503: UCHAR *r_key;
504: ULONG *plane;
505: {
506: ULONG l_text,r_text,
507: l_work,r_work,tmp_text;
508: UCHAR *tmp_k;
509: int loop;
510:
511:
512: l_text = *cipher;
513: r_text = *(cipher+1);
514:
515:
516: /* 初期転置(IP) */
517: l_work = 0x00000000L;
518: r_work = 0x00000000l;
519: for(loop = 0;loop < 64;loop++)
520: {
521: if(loop < 32)
522: {
523: if(ip_1[loop] < 32)
524: {
525: if(l_text & (0x80000000L >> ip_1[loop]))
526: l_work |= 0x80000000L >> loop;
527: }
528: else
529: {
530: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
531: l_work |= 0x80000000L >> loop;
532: }
533: }
534: else
535: {
536: if(ip_1[loop] < 32)
537: {
538: if(l_text & (0x80000000L >> ip_1[loop]))
539: r_work |= 0x80000000l >> (loop - 32);
540: }
541: else
542: {
543: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
544: r_work |= 0x80000000L >> (loop - 32);
545: }
546: }
547: }
548: l_text = l_work;
549: r_text = r_work;
550:
551: /* 段関数 f(R,K) */
552: tmp_k = r_key+90;
553: for(loop = 0;loop < ROUND;loop++,tmp_k-=6)
554: {
555: tmp_text = l_text;
556: l_text = r_text;
557: r_text = tmp_text ^ round_func(r_text,tmp_k);
558:
559: #ifdef DEBUG
560: printf("round[%d] l_text: %08x, r_text: %08x.\n",loop,l_text,r_text);
561: #endif
562:
563: }
564: tmp_text = l_text;
565: l_text = r_text;
566: r_text = tmp_text;
567:
568: /* 最終転置(IP^-1) */
569: l_work = 0x00000000L;
570: r_work = 0x00000000L;
571: for(loop = 0;loop < 64;loop++)
572: {
573: if(loop < 32)
574: {
575: if(ip_2[loop] < 32)
576: {
577: if(l_text & (0x80000000L >> ip_2[loop]))
578: l_work |= 0x80000000L >> loop;
579: }
580: else
581: {
582: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
583: l_work |= 0x80000000L >> loop;
584: }
585: }
586: else
587: {
588: if(ip_2[loop] < 32)
589: {
590: if(l_text & (0x80000000L >> ip_2[loop]))
591: r_work |= 0x80000000L >> (loop - 32);
592: }
593: else
594: {
595: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
596: r_work |= 0x80000000L >> (loop - 32);
597: }
598: }
599: }
600: l_text = l_work;
601: r_text = r_work;
602:
603: *plane = l_text;
604: *(plane+1) = r_text;
605:
606: return;
607: }
608:
609:
610: /****************************************************************************
611: * *
612: * 鍵スケジュール関数 *
613: * void key_schedule(key) *
614: * UCHAR *key : 暗号化鍵(64 bit) (input) *
615: * *
616: * 機能 : 暗号化鍵を入力とし、DESの鍵スケジュールアルゴリズムに基づ *
617: * き段毎の拡大鍵を生成し、大域変数(EX_KEY[96])に格納する。 *
618: * 戻り値 : なし *
619: * *
620: ****************************************************************************/
621: void key_schedule(key,ex_key)
622: UCHAR *key,*ex_key;
623: {
624: UCHAR r_key[6],*k_p;
625: ULONG k_work1,k_work2,
626: c_key,d_key,
627: c_tmp,d_tmp;
1.6 ! noro 628: int loop,loop2;
1.1 noro 629:
630:
631: k_work1 = 0x00000000L;
632: k_work2 = 0x00000000L;
633: k_work1 |= ((ULONG)*key << 24) | ((ULONG)*(key+1) << 16)
634: | ((ULONG)*(key+2) << 8) | (ULONG)*(key+3);
635: k_work2 |= ((ULONG)*(key+4) << 24) | ((ULONG)*(key+5) << 16)
636: | ((ULONG)*(key+6) << 8) | (ULONG)*(key+7);
637:
638: /* 鍵の縮約転置(PC-1) */
639: c_key = 0x00000000L;
640: d_key = 0x00000000L;
641: for(loop = 0;loop < 56;loop++)
642: {
643: if(loop < 28)
644: {
645: if(pc_1[loop] < 32)
646: {
647: if(k_work1 & (0x80000000L >> pc_1[loop]))
648: c_key |= 0x80000000L >> loop;
649: }
650: else
651: {
652: if(k_work2 & (0x80000000L >> pc_1[loop] - 32))
653: c_key |= 0x80000000L >> loop;
654: }
655: }
656: else
657: {
658: if(pc_1[loop] < 32)
659: {
660: if(k_work1 & (0x80000000L >> pc_1[loop]))
661: d_key |= 0x80000000L >> (loop - 28);
662: }
663: else
664: {
665: if(k_work2 & (0x80000000L >> pc_1[loop] - 32))
666: d_key |= 0x80000000L >> (loop - 28);
667: }
668: }
669: }
670:
671: #ifdef DEBUG
672: printf("c: %08x,d: %08x.\n",c_key,d_key);
673: #endif
674:
675: k_p = ex_key;
676: for(loop = 0;loop < 16;loop++,k_p+=6)
677: {
678: /* 鍵のシフト */
679: c_tmp = 0x00000000L;
680: d_tmp = 0x00000000L;
681: c_tmp = (c_key << k_rot[loop]) | (c_key >> (28-k_rot[loop]));
682: d_tmp = (d_key << k_rot[loop]) | (d_key >> (28-k_rot[loop]));
683:
684: /* 鍵の縮約型転置(PC-2) */
685: memset(r_key,0x00L,6);
686: for(loop2 = 0;loop2 < 48;loop2++)
687: {
688: if(pc_2[loop2] < 28)
689: {
690: if(c_tmp & (0x80000000L >> pc_2[loop2]))
691: r_key[loop2 / 8] |= 0x80 >> (loop2 % 8);
692: }
693: else
694: {
695: if(d_tmp & (0x80000000L >> pc_2[loop2]-28))
696: r_key[loop2 / 8] |= (0x80 >> (loop2 % 8));
697: }
698: }
699:
700: memcpy(k_p,r_key,6);
701:
702: #ifdef DEBUG
703: printf("key[%d]: %02x %02x %02x %02x %02x %02x\n",
704: loop,r_key[0],r_key[1],r_key[2],r_key[3],r_key[4],r_key[5]) ;
705: #endif
706: }
707: }
708:
709: #if 0
710: /* 動作確認用main */
711: void main(void)
712: {
713: ULONG p_text[2],c_text[2];
714: UCHAR key[8] =
715: /*{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};*/
716: /*{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};*/
717: { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
718: /*{ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};*/
719: /*{ 0x03,0x96,0x49,0xc5,0x39,0x31,0x39,0x65};*/
720: int loop;
721:
722:
723: /*p_text[0] = 0x00000000;
724: p_text[1] = 0x00000000;*/
725: p_text[0] = 0x01234567L;
726: p_text[1] = 0x89abcde7L;
727: /*p_text[0] = 0xffffffff;
728: p_text[1] = 0xffffffff;*/
729:
730: /*printf("plane: %08x%08x.\n",p_text[0],p_text[1]);*/
731:
732:
733: for(loop =0;loop < 1024*10;loop++)
734: {
735: key_schedule(key);
736: des_enc(p_text,EX_KEY,c_text);
737: /*printf("cipher: %08x%08x.\n\n",c_text[0],c_text[1]);*/
738:
739: /*p_text[0] = c_text[0];
740: p_text[1] = c_text[1];*/
741: }
742:
743: /*des_dec(c_text,EX_KEY,p_text);
744: printf("plane: %08x%08x.\n",p_text[0],p_text[1]);*/
745:
746: }
747: #endif
748:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>