Annotation of OpenXM_contrib2/asir2000/io/des.c, Revision 1.2
1.2 ! noro 1: /*
! 2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
! 3: * All rights reserved.
! 4: *
! 5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
! 6: * non-exclusive and royalty-free license to use, copy, modify and
! 7: * redistribute, solely for non-commercial and non-profit purposes, the
! 8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
! 9: * conditions of this Agreement. For the avoidance of doubt, you acquire
! 10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
! 11: * third party developer retains all rights, including but not limited to
! 12: * copyrights, in and to the SOFTWARE.
! 13: *
! 14: * (1) FLL does not grant you a license in any way for commercial
! 15: * purposes. You may use the SOFTWARE only for non-commercial and
! 16: * non-profit purposes only, such as academic, research and internal
! 17: * business use.
! 18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
! 19: * international copyright treaties. If you make copies of the SOFTWARE,
! 20: * with or without modification, as permitted hereunder, you shall affix
! 21: * to all such copies of the SOFTWARE the above copyright notice.
! 22: * (3) An explicit reference to this SOFTWARE and its copyright owner
! 23: * shall be made on your publication or presentation in any form of the
! 24: * results obtained by use of the SOFTWARE.
! 25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
! 26: * e-mail at risa-admin@flab.fujitsu.co.jp of the detailed specification
! 27: * for such modification or the source code of the modified part of the
! 28: * SOFTWARE.
! 29: *
! 30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
! 31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
! 32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
! 33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
! 34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
! 35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
! 36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
! 37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
! 38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
! 39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
! 40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
! 41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
! 42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
! 43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
! 44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
! 45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
! 46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
! 47: /* $OpenXM: OpenXM_contrib2/asir2000/io/des.c,v 1.1.1.1 1999/12/03 07:39:11 noro Exp $
! 48: */
1.1 noro 49: /* Copyright (C) 1996 S.Amada */
50:
51: #include <stdio.h>
52: #include <stdlib.h>
53:
54: #define ROUND 16 /* 段数 */
55:
56: typedef unsigned long ULONG;
57: typedef unsigned short USHORT;
58: typedef unsigned char UCHAR;
59:
60:
61: /* 関数のproto type */
62: void des_enc(ULONG *, UCHAR *, ULONG *);
63: ULONG round_func(ULONG , UCHAR *);
64: ULONG s_box_func(UCHAR *);
65: void des_dec(ULONG *, UCHAR *, ULONG *);
66:
67: /* 鍵の縮約型転置 PC-1 */
68: static USHORT pc_1[56] = {
69: 56, 48, 40, 32, 24, 16, 8,
70: 0, 57, 49, 41, 33, 25, 17,
71: 9, 1, 58, 50, 42, 34, 26,
72: 18, 10, 2, 59, 51, 43, 35,
73: 62, 54, 46, 38, 30, 22, 14,
74: 6, 61, 53, 45, 37, 29, 21,
75: 13, 5, 60, 52, 44, 36, 28,
76: 20, 12, 4, 27, 19, 11, 3
77: };
78:
79: /* 鍵のシフト回数 */
80: static USHORT k_rot[16] = {
81: 1, 2, 4, 6, 8, 10, 12, 14,
82: 15, 17, 19, 21, 23, 25, 27, 28
83: };
84:
85: /* 鍵の縮約型転置 PC-2 */
86: static USHORT pc_2[48] = {
87: 13, 16, 10, 23, 0, 4,
88: 2, 27, 14, 5, 20, 9,
89: 22, 18, 11, 3, 25, 7,
90: 15, 6, 26, 19, 12, 1,
91: 40, 51, 30, 36, 46, 54,
92: 29, 39, 50, 44, 32, 47,
93: 43, 48, 38, 55, 33, 52,
94: 45, 41, 49, 35, 28, 31
95: };
96:
97: /* 初期転置(IP) */
98: static USHORT ip_1[64] = {
99: 57, 49, 41, 33, 25, 17, 9, 1,
100: 59, 51, 43, 35, 27, 19, 11, 3,
101: 61, 53, 45, 37, 29, 21, 13, 5,
102: 63, 55, 47, 39, 31, 23, 15, 7,
103: 56, 48, 40, 32, 24, 16, 8, 0,
104: 58, 50, 42, 34, 26, 18, 10, 2,
105: 60, 52, 44, 36, 28, 20, 12, 4,
106: 62, 54, 46, 38, 30, 22, 14, 6
107: };
108:
109: /* 初期転置(IP^-1) */
110: static USHORT ip_2[64] = {
111: 39, 7, 47, 15, 55, 23, 63, 31,
112: 38, 6, 46, 14, 54, 22, 62, 30,
113: 37, 5, 45, 13, 53, 21, 61, 29,
114: 36, 4, 44, 12, 52, 20, 60, 28,
115: 35, 3, 43, 11, 51, 19, 59, 27,
116: 34, 2, 42, 10, 50, 18, 58, 26,
117: 33, 1, 41, 9, 49, 17, 57, 25,
118: 32, 0, 40, 8, 48, 16, 56, 24
119: };
120:
121: /* 拡大転置(E) */
122: static USHORT f_expand[48] = {
123: 31, 0, 1, 2, 3, 4,
124: 3, 4, 5, 6, 7, 8,
125: 7, 8, 9, 10, 11, 12,
126: 11, 12, 13, 14, 15, 16,
127: 15, 16, 17, 18, 19, 20,
128: 19, 20, 21, 22, 23, 24,
129: 23, 24, 25, 26, 27, 28,
130: 27, 28, 29, 30, 31, 0
131: };
132:
133: /* S-box */
134: static USHORT s_1[64] = {
135: 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
136: 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
137: 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
138: 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
139: };
140:
141: static USHORT s_2[64] = {
142: 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
143: 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
144: 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
145: 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
146: };
147:
148: static USHORT s_3[64] = {
149: 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
150: 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
151: 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
152: 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
153: };
154:
155: static USHORT s_4[64] = {
156: 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
157: 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
158: 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
159: 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
160: };
161:
162: static USHORT s_5[64] = {
163: 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
164: 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
165: 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
166: 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
167: };
168:
169: static USHORT s_6[64] = {
170: 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
171: 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
172: 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
173: 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
174: };
175:
176: static USHORT s_7[64] = {
177: 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
178: 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
179: 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
180: 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
181: };
182:
183: static USHORT s_8[64] = {
184: 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
185: 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
186: 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
187: 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
188: };
189:
190: /* 転置(P) */
191: static USHORT f_perm[32] = {
192: 15, 6, 19, 20,
193: 28, 11, 27, 16,
194: 0, 14, 22, 25,
195: 4, 17, 30, 9,
196: 1, 7, 23, 13,
197: 31, 26, 2, 8,
198: 18, 12, 29, 5,
199: 21, 10, 3, 24
200: };
201:
202:
203: /****************************************************************************
204: * *
205: * 暗号化関数 *
206: * void des_enc(plane,r_key,cipher) *
207: * ULONG *plane : 平文(64 bit) (input) *
208: * UCHAR *r_key : 拡大鍵(48 * 16 bit) (input) *
209: * ULONG *cipher : 暗号文(64 bit) (output) *
210: * *
211: * 機能 : 平文及び拡大鍵を入力とし、DESのアルゴリズムに基づき暗号文 *
212: * を生成する。 *
213: * 戻り値 : なし *
214: * *
215: ****************************************************************************/
216: void des_enc(plane,r_key,cipher)
217: ULONG *plane; /* 平文(64 bit) */
218: UCHAR *r_key; /* 拡大鍵(48 * 16 bit) */
219: ULONG *cipher; /* 暗号文(64 bit) */
220: {
221: ULONG l_text,r_text,
222: l_work,r_work,tmp_text,c_text[2];
223: int loop;
224:
225:
226: l_text = *plane;
227: r_text = *(plane+1);
228:
229: /* 初期転置(IP) */
230: l_work = 0x00000000L;
231: r_work = 0x00000000L;
232: for(loop = 0;loop < 64;loop++)
233: {
234: if(loop < 32)
235: {
236: if(ip_1[loop] < 32)
237: {
238: if(l_text & (0x80000000L >> ip_1[loop]))
239: l_work |= 0x80000000L >> loop;
240: }
241: else
242: {
243: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
244: l_work |= 0x80000000L >> loop;
245: }
246: }
247: else
248: {
249: if(ip_1[loop] < 32)
250: {
251: if(l_text & (0x80000000L >> ip_1[loop]))
252: r_work |= 0x80000000L >> (loop - 32);
253: }
254: else
255: {
256: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
257: r_work |= 0x80000000L >> (loop - 32);
258: }
259: }
260: }
261: l_text = l_work;
262: r_text = r_work;
263:
264: #ifdef DEBUG
265: printf("l_text: %08x,r_text: %08x.\n",l_text,r_text);
266: #endif
267:
268: /* 段関数 f(R,K) */
269: for(loop = 0;loop < ROUND;loop++,r_key+=6)
270: {
271: tmp_text = l_text;
272: l_text = r_text;
273: r_text = (ULONG)tmp_text ^ (ULONG)round_func(r_text,r_key);
274: #ifdef DEBUG
275: printf("round[%d] l_text: %08x, r_text: %08x.\n",loop,l_text,r_text);
276: #endif
277: }
278: tmp_text = l_text;
279: l_text = r_text;
280: r_text = tmp_text;
281:
282: /* 最終転置(IP^-1) */
283: l_work = 0x00000000L;
284: r_work = 0x00000000L;
285: for(loop = 0;loop < 64;loop++)
286: {
287: if(loop < 32)
288: {
289: if(ip_2[loop] < 32)
290: {
291: if(l_text & (0x80000000L >> ip_2[loop]))
292: l_work |= 0x80000000L >> loop;
293: }
294: else
295: {
296: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
297: l_work |= 0x80000000L >> loop;
298: }
299: }
300: else
301: {
302: if(ip_2[loop] < 32)
303: {
304: if(l_text & (0x80000000L >> ip_2[loop]))
305: r_work |= 0x80000000L >> (loop - 32);
306: }
307: else
308: {
309: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
310: r_work |= 0x80000000L >> (loop - 32);
311: }
312: }
313: }
314: /*l_text = l_work;
315: r_text = r_work;*/
316:
317: #ifdef DEBUG
318: printf("l_text: %08x,r_text: %08x.\n",l_text,r_text);
319: #endif
320:
321: *cipher = l_work;
322: *(cipher+1) = r_work;
323:
324: return;
325: }
326:
327:
328: /****************************************************************************
329: * *
330: * 段関数(f(R,K) *
331: * ULONG round_func(text,key) *
332: * ULONG text : 入力文(32 bit) (input) *
333: * UCHAR *key : 拡大鍵(48 bit) (input) *
334: * *
335: * 機能 : 入力文及び拡大鍵を入力とし、DESの段関数の出力を返す。 *
336: * 戻り値 : 段関数(f(R,K))の出力値 *
337: * *
338: ****************************************************************************/
339: ULONG round_func(text,key)
340: ULONG text;
341: UCHAR *key;
342: {
343: UCHAR e_val[6],k_work[6];
344: ULONG t_work,t_val;
345: int loop;
346:
347:
348: t_work = text;
349:
350: /* 拡大転置(E) 32bit(4byte) -> 48bit(6byte) */
351: memset(e_val,0x00L,6);
352: for(loop = 0;loop < 48;loop++)
353: if(t_work & (0x80000000L >> f_expand[loop]))
354: e_val[loop / 8] |= 0x80L >> (loop % 8);
355:
356: #ifdef DEBUG
357: printf("Expand: %02x%02x%02x%02x%02x%02x.\n",
358: e_val[0],e_val[1],e_val[2],e_val[3],e_val[4],e_val[5]);
359: #endif
360:
361: /* 鍵との排他的論理和演算 48bit(6byte) -> 48bit(6byte) */
362: memset(k_work,0x00L,6);
363: for(loop = 0;loop < 6;loop++,key++)
364: k_work[loop] = e_val[loop] ^ *key;
365:
366: #ifdef DEBUG
367: printf("Key EXORed: %02x%02x%02x%02x%02x%02x.\n",
368: k_work[0],k_work[1],k_work[2],k_work[3],k_work[4],k_work[5]);
369: #endif
370:
371: /* S-box 48bit(6byte) -> 32bit(4byte) */
372: t_work = s_box_func(k_work);
373:
374: #ifdef DEBUG
375: printf("s-box value: %08x.\n",t_work);
376: #endif
377:
378: /* 転置(P) 32bit(4byte) -> 32bit(4byte) */
379: t_val = 0x00000000L;
380: for(loop = 0;loop < 32;loop++)
381: if(t_work & (0x80000000L >> f_perm[loop]))
382: t_val |= 0x80000000L >> loop;
383:
384: #ifdef DEBUG
385: printf("Round func value: %08x.\n",t_val);
386: #endif
387:
388: return(t_val);
389: }
390:
391:
392: /****************************************************************************
393: * *
394: * 段関数(f(R,K) *
395: * ULONG s_box_func(i_data) *
396: * UCHAR *i_data : 入力文(48 bit) (input) *
397: * *
398: * 機能 : 入力文を入力とし、DESのS-Boxの出力値(32 bit)を返す。 *
399: * 戻り値 : S-Boxの出力値 *
400: * *
401: ****************************************************************************/
402: ULONG s_box_func(i_data)
403: UCHAR *i_data;
404: {
405: int loop;
406: UCHAR work[6],s_work[8],val;
407: ULONG fval;
408:
409:
410: for(loop = 0;loop < 6;loop++,i_data++) work[loop] = *i_data;
411:
412: /* S1 */
413: s_work[0] = (work[0] >> 2) & 0x3fL;
414: val = (s_work[0] >> 1) & 0x0fL;
415: if(s_work[0] & 0x20L)
416: {
417: if(s_work[0] & 0x01L) s_work[0] = s_1[val+48];
418: else s_work[0] = s_1[val+32];
419: }
420: else
421: {
422: if(s_work[0] & 0x01L) s_work[0] = s_1[val+16];
423: else s_work[0] = s_1[val];
424: }
425:
426: /* S2 */
427: s_work[1] = ((work[0] << 4) | (work[1] >> 4)) & 0x3fL;
428: val = (s_work[1] >> 1) & 0x0fL;
429: if(s_work[1] & 0x20L)
430: {
431: if(s_work[1] & 0x01L) s_work[1] = s_2[val+48];
432: else s_work[1] = s_2[val+32];
433: }
434: else
435: {
436: if(s_work[1] & 0x01L) s_work[1] = s_2[val+16];
437: else s_work[1] = s_2[val];
438: }
439:
440: /* S3 */
441: s_work[2] = ((work[1] << 2) | (work[2] >> 6)) & 0x3fL;
442: val = (s_work[2] >> 1) & 0x0fL;
443: if(s_work[2] & 0x20L)
444: {
445: if(s_work[2] & 0x01L) s_work[2] = s_3[val+48];
446: else s_work[2] = s_3[val+32];
447: }
448: else
449: {
450: if(s_work[2] & 0x01L) s_work[2] = s_3[val+16];
451: else s_work[2] = s_3[val];
452: }
453:
454: /* S4 */
455: s_work[3] = work[2] & 0x3fL;
456: val = (s_work[3] >> 1) & 0x0fL;
457: if(s_work[3] & 0x20L)
458: {
459: if(s_work[3] & 0x01L) s_work[3] = s_4[val+48];
460: else s_work[3] = s_4[val+32];
461: }
462: else
463: {
464: if(s_work[3] & 0x01L) s_work[3] = s_4[val+16];
465: else s_work[3] = s_4[val];
466: }
467:
468: /* S5 */
469: s_work[4] = (work[3] >> 2) & 0x3fL;
470: val = (s_work[4] >> 1) & 0x0fL;
471: if(s_work[4] & 0x20L)
472: {
473: if(s_work[4] & 0x01L) s_work[4] = s_5[val+48];
474: else s_work[4] = s_5[val+32];
475: }
476: else
477: {
478: if(s_work[4] & 0x01L) s_work[4] = s_5[val+16];
479: else s_work[4] = s_5[val];
480: }
481:
482: /* S6 */
483: s_work[5] = ((work[3] << 4) | (work[4] >> 4)) & 0x3fL;
484: val = (s_work[5] >> 1) & 0x0fL;
485: if(s_work[5] & 0x20L)
486: {
487: if(s_work[5] & 0x01L) s_work[5] = s_6[val+48];
488: else s_work[5] = s_6[val+32];
489: }
490: else
491: {
492: if(s_work[5] & 0x01L) s_work[5] = s_6[val+16];
493: else s_work[5] = s_6[val];
494: }
495:
496: /* S7 */
497: s_work[6] = ((work[4] << 2) | (work[5] >> 6)) & 0x3fL;
498: val = (s_work[6] >> 1) & 0x0fL;
499: if(s_work[6] & 0x20L)
500: {
501: if(s_work[6] & 0x01L) s_work[6] = s_7[val+48];
502: else s_work[6] = s_7[val+32];
503: }
504: else
505: {
506: if(s_work[6] & 0x01L) s_work[6] = s_7[val+16];
507: else s_work[6] = s_7[val];
508: }
509:
510: /* S8 */
511: s_work[7] = work[5] & 0x3fL;
512: val = (s_work[7] >> 1) & 0x0fL;
513: if(s_work[7] & 0x20L)
514: {
515: if(s_work[7] & 0x01L) s_work[7] = s_8[val+48];
516: else s_work[7] = s_8[val+32];
517: }
518: else
519: {
520: if(s_work[7] & 0x01L) s_work[7] = s_8[val+16];
521: else s_work[7] = s_8[val];
522: }
523:
524: fval = (s_work[0] << 28) | (s_work[1] << 24)
525: | (s_work[2] << 20) | (s_work[3] << 16)
526: | (s_work[4] << 12) | (s_work[5] << 8)
527: | (s_work[6] << 4) | s_work[7];
528:
529: return(fval);
530: }
531:
532:
533: /****************************************************************************
534: * *
535: * 復号関数 *
536: * void des_dec(cipher,r_key,plane) *
537: * ULONG *cipher : 暗号文(64 bit) (output) *
538: * UCHAR *r_key : 拡大鍵(48 * 16 bit) (input) *
539: * ULONG *plane : 平文(64 bit) (input) *
540: * *
541: * 機能 : 暗号文及び拡大鍵を入力とし、DESのアルゴリズムに基づき平文 *
542: * を生成する。 *
543: * 戻り値 : なし *
544: * *
545: ****************************************************************************/
546: void des_dec(cipher,r_key,plane)
547: ULONG *cipher;
548: UCHAR *r_key;
549: ULONG *plane;
550: {
551: ULONG l_text,r_text,
552: l_work,r_work,tmp_text;
553: UCHAR *tmp_k;
554: int loop;
555:
556:
557: l_text = *cipher;
558: r_text = *(cipher+1);
559:
560:
561: /* 初期転置(IP) */
562: l_work = 0x00000000L;
563: r_work = 0x00000000l;
564: for(loop = 0;loop < 64;loop++)
565: {
566: if(loop < 32)
567: {
568: if(ip_1[loop] < 32)
569: {
570: if(l_text & (0x80000000L >> ip_1[loop]))
571: l_work |= 0x80000000L >> loop;
572: }
573: else
574: {
575: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
576: l_work |= 0x80000000L >> loop;
577: }
578: }
579: else
580: {
581: if(ip_1[loop] < 32)
582: {
583: if(l_text & (0x80000000L >> ip_1[loop]))
584: r_work |= 0x80000000l >> (loop - 32);
585: }
586: else
587: {
588: if(r_text & (0x80000000L >> (ip_1[loop] - 32)))
589: r_work |= 0x80000000L >> (loop - 32);
590: }
591: }
592: }
593: l_text = l_work;
594: r_text = r_work;
595:
596: /* 段関数 f(R,K) */
597: tmp_k = r_key+90;
598: for(loop = 0;loop < ROUND;loop++,tmp_k-=6)
599: {
600: tmp_text = l_text;
601: l_text = r_text;
602: r_text = tmp_text ^ round_func(r_text,tmp_k);
603:
604: #ifdef DEBUG
605: printf("round[%d] l_text: %08x, r_text: %08x.\n",loop,l_text,r_text);
606: #endif
607:
608: }
609: tmp_text = l_text;
610: l_text = r_text;
611: r_text = tmp_text;
612:
613: /* 最終転置(IP^-1) */
614: l_work = 0x00000000L;
615: r_work = 0x00000000L;
616: for(loop = 0;loop < 64;loop++)
617: {
618: if(loop < 32)
619: {
620: if(ip_2[loop] < 32)
621: {
622: if(l_text & (0x80000000L >> ip_2[loop]))
623: l_work |= 0x80000000L >> loop;
624: }
625: else
626: {
627: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
628: l_work |= 0x80000000L >> loop;
629: }
630: }
631: else
632: {
633: if(ip_2[loop] < 32)
634: {
635: if(l_text & (0x80000000L >> ip_2[loop]))
636: r_work |= 0x80000000L >> (loop - 32);
637: }
638: else
639: {
640: if(r_text & (0x80000000L >> (ip_2[loop] - 32)))
641: r_work |= 0x80000000L >> (loop - 32);
642: }
643: }
644: }
645: l_text = l_work;
646: r_text = r_work;
647:
648: *plane = l_text;
649: *(plane+1) = r_text;
650:
651: return;
652: }
653:
654:
655: /****************************************************************************
656: * *
657: * 鍵スケジュール関数 *
658: * void key_schedule(key) *
659: * UCHAR *key : 暗号化鍵(64 bit) (input) *
660: * *
661: * 機能 : 暗号化鍵を入力とし、DESの鍵スケジュールアルゴリズムに基づ *
662: * き段毎の拡大鍵を生成し、大域変数(EX_KEY[96])に格納する。 *
663: * 戻り値 : なし *
664: * *
665: ****************************************************************************/
666: void key_schedule(key,ex_key)
667: UCHAR *key,*ex_key;
668: {
669: UCHAR r_key[6],*k_p;
670: ULONG k_work1,k_work2,
671: c_key,d_key,
672: c_tmp,d_tmp;
673: int loop,loop2,len,strcnt;
674:
675:
676: k_work1 = 0x00000000L;
677: k_work2 = 0x00000000L;
678: k_work1 |= ((ULONG)*key << 24) | ((ULONG)*(key+1) << 16)
679: | ((ULONG)*(key+2) << 8) | (ULONG)*(key+3);
680: k_work2 |= ((ULONG)*(key+4) << 24) | ((ULONG)*(key+5) << 16)
681: | ((ULONG)*(key+6) << 8) | (ULONG)*(key+7);
682:
683: /* 鍵の縮約転置(PC-1) */
684: c_key = 0x00000000L;
685: d_key = 0x00000000L;
686: for(loop = 0;loop < 56;loop++)
687: {
688: if(loop < 28)
689: {
690: if(pc_1[loop] < 32)
691: {
692: if(k_work1 & (0x80000000L >> pc_1[loop]))
693: c_key |= 0x80000000L >> loop;
694: }
695: else
696: {
697: if(k_work2 & (0x80000000L >> pc_1[loop] - 32))
698: c_key |= 0x80000000L >> loop;
699: }
700: }
701: else
702: {
703: if(pc_1[loop] < 32)
704: {
705: if(k_work1 & (0x80000000L >> pc_1[loop]))
706: d_key |= 0x80000000L >> (loop - 28);
707: }
708: else
709: {
710: if(k_work2 & (0x80000000L >> pc_1[loop] - 32))
711: d_key |= 0x80000000L >> (loop - 28);
712: }
713: }
714: }
715:
716: #ifdef DEBUG
717: printf("c: %08x,d: %08x.\n",c_key,d_key);
718: #endif
719:
720: k_p = ex_key;
721: for(loop = 0;loop < 16;loop++,k_p+=6)
722: {
723: /* 鍵のシフト */
724: c_tmp = 0x00000000L;
725: d_tmp = 0x00000000L;
726: c_tmp = (c_key << k_rot[loop]) | (c_key >> (28-k_rot[loop]));
727: d_tmp = (d_key << k_rot[loop]) | (d_key >> (28-k_rot[loop]));
728:
729: /* 鍵の縮約型転置(PC-2) */
730: memset(r_key,0x00L,6);
731: for(loop2 = 0;loop2 < 48;loop2++)
732: {
733: if(pc_2[loop2] < 28)
734: {
735: if(c_tmp & (0x80000000L >> pc_2[loop2]))
736: r_key[loop2 / 8] |= 0x80 >> (loop2 % 8);
737: }
738: else
739: {
740: if(d_tmp & (0x80000000L >> pc_2[loop2]-28))
741: r_key[loop2 / 8] |= (0x80 >> (loop2 % 8));
742: }
743: }
744:
745: memcpy(k_p,r_key,6);
746:
747: #ifdef DEBUG
748: printf("key[%d]: %02x %02x %02x %02x %02x %02x\n",
749: loop,r_key[0],r_key[1],r_key[2],r_key[3],r_key[4],r_key[5]) ;
750: #endif
751: }
752: }
753:
754: #if 0
755: /* 動作確認用main */
756: void main(void)
757: {
758: ULONG p_text[2],c_text[2];
759: UCHAR key[8] =
760: /*{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};*/
761: /*{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};*/
762: { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
763: /*{ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};*/
764: /*{ 0x03,0x96,0x49,0xc5,0x39,0x31,0x39,0x65};*/
765: int loop;
766:
767:
768: /*p_text[0] = 0x00000000;
769: p_text[1] = 0x00000000;*/
770: p_text[0] = 0x01234567L;
771: p_text[1] = 0x89abcde7L;
772: /*p_text[0] = 0xffffffff;
773: p_text[1] = 0xffffffff;*/
774:
775: /*printf("plane: %08x%08x.\n",p_text[0],p_text[1]);*/
776:
777:
778: for(loop =0;loop < 1024*10;loop++)
779: {
780: key_schedule(key);
781: des_enc(p_text,EX_KEY,c_text);
782: /*printf("cipher: %08x%08x.\n\n",c_text[0],c_text[1]);*/
783:
784: /*p_text[0] = c_text[0];
785: p_text[1] = c_text[1];*/
786: }
787:
788: /*des_dec(c_text,EX_KEY,p_text);
789: printf("plane: %08x%08x.\n",p_text[0],p_text[1]);*/
790:
791: }
792: #endif
793:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>