1 /*
2  * enc.c
3  */
4 
5 /*
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /*
10  * This is a model of the enigma hardware as remembered from
11  * a description read around ten years prior.  The model has
12  * not been tested or validated as cryptographically secure.
13  * Furthermore the author intentionally did not validate the
14  * model against published descriptions of the enigma.  The
15  * only test completed was to set the wheels to a known
16  * position and insert a pt string of text into the function.
17  * The output was recorded as ct.  The wheels were reset to the
18  * original start position, and the recorded ct was inserted
19  * into the function.  The output was compared to the original
20  * pt text and matched.  The result of the test matched the
21  * expected outcome, but it does not validate the algorithm
22  * meets any security requirements.
23  *
24  * **********************************************************
25  *
26  * DO NOT USE IN PRODUCTION CODE AS A SECURITY FEATURE
27  *
28  * **********************************************************
29  */
30 
31 #include "enc.h"
32 
33 
34 /*
35  * for a pt character encrypt a ct character and update wheels
36  * Each wheel must be indexed into and out of the wheel arrays
37  * this process is based on a absolute index of input characters
38  * and the reflector.
39  * Note: the output of wheel arrays are added to WHEEL_SIZE
40  * to prevent a negative index when subtracting the iw value.
41  * The printk lines have been left in to inspect operations
42  * of the enigma simulation. simply add the definition DBUG
43  * to enable the detailed messages.
44  */
45 
enig_enc(char pt)46 char enig_enc(char pt)
47 {
48 	short tmpIndex;
49 	char ct;
50 #ifdef DBUG
51 	printk("\nEE PT: %c, %02x\n", pt, pt);
52 	printk("Index: %d, %d, %d\n", IW1, IW2, IW3);
53 #endif
54 	tmpIndex = char_to_index(pt);
55 #ifdef DBUG
56 	printk("EE   : %02x\n", tmpIndex);
57 #endif
58 	/* if error return  */
59 	if (tmpIndex == -1) {
60 		return (char)0xFF;
61 	}
62 
63 	tmpIndex = (W1[IMOD(IW1, tmpIndex)] + WHEEL_SIZE - IW1) % WHEEL_SIZE;
64 #ifdef DBUG
65 	printk("EE i1: %02x\n", tmpIndex);
66 #endif
67 	tmpIndex = (W2[IMOD(IW2, tmpIndex)] +  WHEEL_SIZE - IW2) % WHEEL_SIZE;
68 #ifdef DBUG
69 	printk("EE i2: %02x\n", tmpIndex);
70 #endif
71 	tmpIndex = (W3[IMOD(IW3, tmpIndex)] + WHEEL_SIZE - IW3) % WHEEL_SIZE;
72 #ifdef DBUG
73 	printk("EE i3: %02x\n", tmpIndex);
74 #endif
75 	tmpIndex = R[tmpIndex];
76 #ifdef DBUG
77 	printk("EE  r: %02x\n", tmpIndex);
78 #endif
79 	tmpIndex = (W3R[IMOD(IW3, tmpIndex)] + WHEEL_SIZE - IW3) % WHEEL_SIZE;
80 #ifdef DBUG
81 	printk("EE i3: %02x\n", tmpIndex);
82 #endif
83 	tmpIndex = (W2R[IMOD(IW2, tmpIndex)] + WHEEL_SIZE - IW2) % WHEEL_SIZE;
84 #ifdef DBUG
85 	printk("EE i2: %02x\n", tmpIndex);
86 #endif
87 	tmpIndex = (W1R[IMOD(IW1, tmpIndex)] + WHEEL_SIZE - IW1) % WHEEL_SIZE;
88 #ifdef DBUG
89 	printk("EE i1: %02x\n", tmpIndex);
90 #endif
91 
92 	ct = index_to_char(tmpIndex);
93 #ifdef DBUG
94 	printk("EE CT: %02x\n", ct);
95 #endif
96 	/* test ct value or just return error ? */
97 	update_wheel_index();
98 	return ct;
99 }
100 
101 /*
102  * calc reverse path for wheel
103  *  this simplifies the reverse path calculation
104  * Return: 1:ok -1 error
105  */
calc_rev_wheel(BYTE * wheel,BYTE * backpath)106 int calc_rev_wheel(BYTE *wheel, BYTE *backpath)
107 {
108 
109 	int i;
110 
111 	for (i = 0; i < WHEEL_SIZE; i++) {
112 		if (wheel[i] >= WHEEL_SIZE) {
113 			return -1;
114 		}
115 		backpath[wheel[i]] = i;
116 	}
117 	return 1;
118 }
119 
120 
121 /*
122  * convert a-z to 0-25
123  */
char_to_index(char c)124 short char_to_index(char c)
125 {
126 	if (c < 'a' || c > 'z') {
127 		return -1;
128 	}
129 	return (short)(c - 'a');
130 }
131 
132 /*
133  *  convert from a index 0-25 to a-z
134  */
index_to_char(short i)135 char index_to_char(short i)
136 {
137 	if (i < 0 || i > 25) {
138 		return 0xFF;
139 	}
140 	return (char)((short)'a' + i);
141 }
142 
143 /*
144  *  basic update to wheels based on full rotation
145  *  of prior wheel.  This could be modified to change
146  *  the direction of rotation or order of updates
147  */
update_wheel_index(void)148 void update_wheel_index(void)
149 {
150 	IW1++;
151 	if (IW1 >= WHEEL_SIZE) {
152 		IW1 %= WHEEL_SIZE;
153 		IW2++;
154 	}
155 	if (IW2 >= WHEEL_SIZE) {
156 		IW2 %= WHEEL_SIZE;
157 		IW3++;
158 	}
159 	if (IW3 >= WHEEL_SIZE) {
160 		IW3 %= WHEEL_SIZE;
161 	}
162 
163 }
164