1
2 /*
3 * This crypt(3) validation program shipped with UFC-crypt
4 * is derived from one distributed with Phil Karns PD DES package.
5 *
6 * @(#)cert.c 1.8 11 Aug 1996
7 */
8
9 #include "crypt-port.h"
10 #include "crypt-obsolete.h"
11 #include "des-cases.h"
12
13 #include <stdio.h>
14
15 #if ENABLE_OBSOLETE_API_ENOSYS
16 #include <errno.h>
17 #endif
18
19 #if HAVE_SYMVER
20 symver_ref("encrypt_r", encrypt_r, SYMVER_FLOOR);
21 symver_ref("setkey_r", setkey_r, SYMVER_FLOOR);
22 #endif
23
24 static void
25 expand (unsigned char ex[64], const unsigned char pk[8])
26 {
27 int i, j;
28 unsigned int t;
29
30 for (i = 0; i < 8; i++)
31 {
32 t = pk[i];
33 for (j = 0; j < 8; j++)
34 ex[i*8 + j] = (unsigned char)((t & (0x01u << (7 - j))) != 0);
35 }
36 }
37
38 #if !ENABLE_OBSOLETE_API_ENOSYS
39
40 static void
41 ex_print (const unsigned char ex[64])
42 {
43 int i, j;
44 unsigned int t;
45
46 for (i = 0; i < 8; i++)
47 {
48 t = 0;
49 for (j = 0; j < 8; j++)
50 t = (t << 1) | ex[i*8 + j];
51 printf ("%02x", t);
52 }
53 }
54
55 static void
56 pk_print (const unsigned char pk[8])
57 {
58 for (int i = 0; i < 8; i++)
59 printf ("%02x", (unsigned int)pk[i]);
60 }
61
62 static void
63 report_failure (size_t n, bool decrypt,
64 const struct des_testcase *tc, const unsigned char got[64])
65 {
66 printf ("FAIL: %zu/%s: k=", n, decrypt ? "de" : "en");
67 pk_print (tc->key);
68 fputs (" exp ", stdout);
69 if (decrypt)
70 pk_print (tc->plain);
71 else
72 pk_print (tc->answer);
73 fputs (" got ", stdout);
74 ex_print (got);
75 putchar ('\n');
76 }
77
78 int
79 main (void)
80 {
81 unsigned char key[64], plain[64], cipher[64], answer[64];
82 const struct des_testcase *tc;
83 size_t t;
84 int status = 0;
85 struct crypt_data data;
86
87 for (t = 0; t < N_DES_TESTCASES; t++)
88 {
89 tc = &des_testcases[t];
90 expand (key, tc->key);
91 expand (plain, tc->plain);
92 expand (answer, tc->answer);
93
94 setkey_r ((char *)key, &data);
95 memcpy (cipher, plain, 64);
96 encrypt_r ((char *)cipher, 0, &data);
97
98 if (memcmp (cipher, answer, 64) != 0)
99 {
100 status = 1;
101 report_failure (t, false, tc, cipher);
102 }
103
104 memcpy (cipher, answer, 64);
105 encrypt_r ((char *)cipher, 1, &data);
106 if (memcmp (cipher, plain, 64) != 0)
107 {
108 status = 1;
109 report_failure (t, true, tc, cipher);
110 }
111 }
112
113 return status;
114 }
115
116 #else
117
118 int
119 main (void)
120 {
121 unsigned char key[64], plain[64], cipher[64], answer[64];
122 const struct des_testcase *tc;
123 size_t t;
124 int status = 0;
125 struct crypt_data data;
126
127 for (t = 0; t < N_DES_TESTCASES; t++)
128 {
129 tc = &des_testcases[t];
130 expand (key, tc->key);
131 expand (plain, tc->plain);
132 expand (answer, tc->answer);
133
134 /* Explicitly reset errno as required by POSIX. */
135 errno = 0;
136
137 setkey_r ((char *)key, &data);
138
139 if (errno != ENOSYS)
140 {
141 status = 1;
142 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
143 "expected: %d, %s, got: %d, %s\n", "setkey_r",
144 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
145 }
146
147 memcpy (cipher, plain, 64);
148
149 /* Explicitly reset errno as required by POSIX. */
150 errno = 0;
151
152 encrypt_r ((char *)cipher, 0, &data);
153
154 if (memcmp (cipher, answer, 64) == 0)
155 {
156 status = 1;
157 printf ("FAIL: %s: still performs correct operation.\n",
158 "encrypt_r");
159 }
160
161 if (memcmp (cipher, plain, 64) == 0)
162 {
163 status = 1;
164 printf ("FAIL: %s: data-block is has not changed.\n",
165 "encrypt_r");
166 }
167
168 if (errno != ENOSYS)
169 {
170 status = 1;
171 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
172 "expected: %d, %s, got: %d, %s\n", "encrypt_r",
173 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
174 }
175
176 /* Explicitly reset errno as required by POSIX. */
177 errno = 0;
178
179 encrypt_r ((char *)cipher, 1, &data);
180
181 if (memcmp (cipher, plain, 64) == 0)
182 {
183 status = 1;
184 printf ("FAIL: %s: still performs correct operation.\n",
185 "encrypt_r (decrypt)");
186 }
187
188 if (memcmp (cipher, answer, 64) == 0)
189 {
190 status = 1;
191 printf ("FAIL: %s: data-block is unchanged.\n",
192 "encrypt_r (decrypt)");
193 }
194
195 if (errno != ENOSYS)
196 {
197 status = 1;
198 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
199 "expected: %d, %s, got: %d, %s\n", "encrypt_r (decrypt)",
200 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
201 }
202 }
203
204 return status;
205 }
206
207 #endif