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", encrypt, SYMVER_FLOOR);
21 symver_ref("setkey", setkey, 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
86 for (t = 0; t < N_DES_TESTCASES; t++)
87 {
88 tc = &des_testcases[t];
89 expand (key, tc->key);
90 expand (plain, tc->plain);
91 expand (answer, tc->answer);
92
93 setkey ((char *)key);
94 memcpy (cipher, plain, 64);
95 encrypt ((char *)cipher, 0);
96
97 if (memcmp (cipher, answer, 64) != 0)
98 {
99 status = 1;
100 report_failure (t, false, tc, cipher);
101 }
102
103 memcpy (cipher, answer, 64);
104 encrypt ((char *)cipher, 1);
105 if (memcmp (cipher, plain, 64) != 0)
106 {
107 status = 1;
108 report_failure (t, true, tc, cipher);
109 }
110 }
111
112 return status;
113 }
114
115 #else
116
117 int
118 main (void)
119 {
120 unsigned char key[64], plain[64], cipher[64], answer[64];
121 const struct des_testcase *tc;
122 size_t t;
123 int status = 0;
124
125 for (t = 0; t < N_DES_TESTCASES; t++)
126 {
127 tc = &des_testcases[t];
128 expand (key, tc->key);
129 expand (plain, tc->plain);
130 expand (answer, tc->answer);
131
132 /* Explicitly reset errno as required by POSIX. */
133 errno = 0;
134
135 setkey ((char *)key);
136
137 if (errno != ENOSYS)
138 {
139 status = 1;
140 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
141 "expected: %d, %s, got: %d, %s\n", "setkey",
142 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
143 }
144
145 memcpy (cipher, plain, 64);
146
147 /* Explicitly reset errno as required by POSIX. */
148 errno = 0;
149
150 encrypt ((char *)cipher, 0);
151
152 if (memcmp (cipher, answer, 64) == 0)
153 {
154 status = 1;
155 printf ("FAIL: %s: still performs correct operation.\n",
156 "encrypt");
157 }
158
159 if (memcmp (cipher, plain, 64) == 0)
160 {
161 status = 1;
162 printf ("FAIL: %s: data-block is has not changed.\n",
163 "encrypt");
164 }
165
166 if (errno != ENOSYS)
167 {
168 status = 1;
169 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
170 "expected: %d, %s, got: %d, %s\n", "encrypt",
171 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
172 }
173
174 /* Explicitly reset errno as required by POSIX. */
175 errno = 0;
176
177 encrypt ((char *)cipher, 1);
178
179 if (memcmp (cipher, plain, 64) == 0)
180 {
181 status = 1;
182 printf ("FAIL: %s: still performs correct operation.\n",
183 "encrypt (decrypt)");
184 }
185
186 if (memcmp (cipher, answer, 64) == 0)
187 {
188 status = 1;
189 printf ("FAIL: %s: data-block is unchanged.\n",
190 "encrypt (decrypt)");
191 }
192
193 if (errno != ENOSYS)
194 {
195 status = 1;
196 printf ("FAIL: %s: errno does NOT equal ENOSYS.\n"
197 "expected: %d, %s, got: %d, %s\n", "encrypt (decrypt)",
198 ENOSYS, strerror (ENOSYS), errno, strerror (errno));
199 }
200 }
201
202 return status;
203 }
204
205 #endif