1 /* CRYPTO.C (c) Copyright Jan Jaeger, 2000-2010 */
2 /* Cryptographic instructions */
3
4 #include "hstdinc.h"
5
6 #define _CRYPTO_C_
7 #define _HENGINE_DLL_
8
9 #include "hercules.h"
10
11 #if defined(FEATURE_MESSAGE_SECURITY_ASSIST)
12
13 #include "opcode.h"
14
15 #define CRYPTO_EXTERN
16 #include "crypto.h"
17
18 /*----------------------------------------------------------------------------*/
19 /* B93E KIMD - Compute Intermediate Message Digest [RRE] */
20 /*----------------------------------------------------------------------------*/
DEF_INST(compute_intermediate_message_digest_r)21 DEF_INST(compute_intermediate_message_digest_r)
22 {
23 if( ARCH_DEP(compute_intermediate_message_digest) )
24 ARCH_DEP(compute_intermediate_message_digest) (inst, regs);
25 else
26 {
27 int r1, r2; /* register values */
28
29 RRE(inst, regs, r1, r2);
30
31 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
32 }
33 }
34
35 /*----------------------------------------------------------------------------*/
36 /* B93F KLMD - Compute Last Message Digest [RRE] */
37 /*----------------------------------------------------------------------------*/
DEF_INST(compute_last_message_digest_r)38 DEF_INST(compute_last_message_digest_r)
39 {
40 if( ARCH_DEP(compute_last_message_digest) )
41 ARCH_DEP(compute_last_message_digest) (inst, regs);
42 else
43 {
44 int r1, r2; /* register values */
45
46 RRE(inst, regs, r1, r2);
47
48 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
49 }
50 }
51
52 /*----------------------------------------------------------------------------*/
53 /* B92E KM - Cipher Message [RRE] */
54 /*----------------------------------------------------------------------------*/
DEF_INST(cipher_message_r)55 DEF_INST(cipher_message_r)
56 {
57 if( ARCH_DEP(cipher_message) )
58 ARCH_DEP(cipher_message) (inst, regs);
59 else
60 {
61 int r1, r2; /* register values */
62
63 RRE(inst, regs, r1, r2);
64
65 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
66 }
67 }
68
69 /*----------------------------------------------------------------------------*/
70 /* B91E KMAC - Compute Message Authentication Code [RRE] */
71 /*----------------------------------------------------------------------------*/
DEF_INST(compute_message_authentication_code_r)72 DEF_INST(compute_message_authentication_code_r)
73 {
74 if( ARCH_DEP(compute_message_authentication_code) )
75 ARCH_DEP(compute_message_authentication_code) (inst, regs);
76 else
77 {
78 int r1, r2; /* register values */
79
80 RRE(inst, regs, r1, r2);
81
82 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
83 }
84 }
85
86 /*----------------------------------------------------------------------------*/
87 /* B92F KMC - Cipher Message with Chaining [RRE] */
88 /*----------------------------------------------------------------------------*/
DEF_INST(cipher_message_with_chaining_r)89 DEF_INST(cipher_message_with_chaining_r)
90 {
91 if( ARCH_DEP(cipher_message_with_chaining) )
92 ARCH_DEP(cipher_message_with_chaining) (inst, regs);
93 else
94 {
95 int r1, r2; /* register values */
96
97 RRE(inst, regs, r1, r2);
98
99 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
100 }
101 }
102
103 #endif /*defined(FEATURE_MESSAGE_SECURITY_ASSIST)*/
104
105 #ifdef FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_4
106 /*----------------------------------------------------------------------------*/
107 /* B92D KMCTR - Cipher message with counter [RRF] */
108 /*----------------------------------------------------------------------------*/
DEF_INST(cipher_message_with_counter_r)109 DEF_INST(cipher_message_with_counter_r)
110 {
111 if( ARCH_DEP(cipher_message_with_counter) )
112 ARCH_DEP(cipher_message_with_counter) (inst, regs);
113 else
114 {
115 int r1, r2, r3; /* register values */
116
117 RRF_M(inst, regs, r1, r2, r3);
118
119 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
120 }
121 }
122
123 /*----------------------------------------------------------------------------*/
124 /* B92A KMF - Cipher message with cipher feedback [RRE] */
125 /*----------------------------------------------------------------------------*/
DEF_INST(cipher_message_with_cipher_feedback_r)126 DEF_INST(cipher_message_with_cipher_feedback_r)
127 {
128 if( ARCH_DEP(cipher_message_with_cipher_feedback) )
129 ARCH_DEP(cipher_message_with_cipher_feedback) (inst, regs);
130 else
131 {
132 int r1, r2; /* register values */
133
134 RRE(inst, regs, r1, r2);
135
136 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
137 }
138 }
139
140 /*----------------------------------------------------------------------------*/
141 /* B92B KMO - Cipher message with output feedback [RRE] */
142 /*----------------------------------------------------------------------------*/
DEF_INST(cipher_message_with_output_feedback_r)143 DEF_INST(cipher_message_with_output_feedback_r)
144 {
145 if( ARCH_DEP(cipher_message_with_output_feedback) )
146 ARCH_DEP(cipher_message_with_output_feedback) (inst, regs);
147 else
148 {
149 int r1, r2; /* register values */
150
151 RRE(inst, regs, r1, r2);
152
153 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
154 }
155 }
156
157 /*----------------------------------------------------------------------------*/
158 /* B92C PCC - Perform cryptographic computation [RRE] */
159 /*----------------------------------------------------------------------------*/
DEF_INST(perform_cryptographic_computation_r)160 DEF_INST(perform_cryptographic_computation_r)
161 {
162 if( ARCH_DEP(perform_cryptographic_computation) )
163 ARCH_DEP(perform_cryptographic_computation) (inst, regs);
164 else
165 {
166 int r1, r2; /* register values */
167
168 RRE(inst, regs, r1, r2);
169
170 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
171 }
172 }
173 #endif /* FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_4 */
174
175 #ifdef FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_3
176 /*----------------------------------------------------------------------------*/
177 /* B928 PCKMO - Perform cryptographic key management operation [RRE] */
178 /*----------------------------------------------------------------------------*/
DEF_INST(perform_cryptographic_key_management_operation_r)179 DEF_INST(perform_cryptographic_key_management_operation_r)
180 {
181 if( ARCH_DEP(perform_cryptographic_key_management_operation) )
182 ARCH_DEP(perform_cryptographic_key_management_operation) (inst, regs);
183 else
184 {
185 int r1, r2; /* register values */
186
187 RRE(inst, regs, r1, r2);
188
189 ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
190 }
191 }
192
193 #ifndef __WK__
194 #define __WK__
195 /*----------------------------------------------------------------------------*/
196 /* Function: renew_wrapping_keys */
197 /* */
198 /* Each time a clear reset is performed, a new set of wrapping keys and their */
199 /* associated verification patterns are generated. The contents of the two */
200 /* wrapping-key registers are kept internal to the model so that no program, */
201 /* including the operating system, can directly observe their clear value. */
202 /*----------------------------------------------------------------------------*/
renew_wrapping_keys(void)203 void renew_wrapping_keys(void)
204 {
205 int i;
206 BYTE lparname[8];
207 U64 cpuid;
208 BYTE byte;
209
210 obtain_lock(&sysblk.wklock);
211 for(i = 0; i < 0x100; i++)
212 srandom(random() * host_tod()); /* Randomize related to time */
213 for(i = 0; i < 32; i++)
214 sysblk.wkaes_reg[i] = random();
215 for(i = 0; i < 24; i++)
216 sysblk.wkdea_reg[i] = random();
217
218 /* We set the verification pattern to */
219 /* cpuid (8 bytes) */
220 /* lpar name (8 bytes) */
221 /* lparnum (1 byte) */
222 /* random number 8 bytes at the end) */
223 memset(sysblk.wkvpaes_reg, 0, 32);
224 memset(sysblk.wkvpdea_reg, 0, 24);
225 cpuid = sysblk.cpuid;
226 for(i = 0; i < 8; i++)
227 {
228 sysblk.wkvpaes_reg[7 - i] = cpuid;
229 sysblk.wkvpdea_reg[7 - i] = cpuid;
230 cpuid >>= 8;
231 }
232 get_lparname(lparname);
233 memcpy(&sysblk.wkvpaes_reg[8], lparname, 8);
234 memcpy(&sysblk.wkvpdea_reg[8], lparname, 8);
235 sysblk.wkvpaes_reg[16] = sysblk.lparnum;
236 sysblk.wkvpdea_reg[16] = sysblk.lparnum;
237 for(i = 0; i < 8; i++)
238 {
239 byte = random();
240 sysblk.wkvpaes_reg[31 - i] = byte;
241 sysblk.wkvpdea_reg[23 - i] = byte;
242 }
243 release_lock(&sysblk.wklock);
244
245 #if 0
246 logmsg("AES wrapping key: ");
247 for(i = 0; i < 32; i++)
248 logmsg("%02X", sysblk.wkaes_reg[i]);
249 logmsg("\nAES wrapping key verification pattern: ");
250 for(i = 0; i < 32; i++)
251 logmsg("%02X", sysblk.wkvpaes_reg[i]);
252 logmsg("\nDEA wrapping key: ");
253 for(i = 0; i < 24; i++)
254 logmsg("%02X", sysblk.wkdea_reg[i]);
255 logmsg("\nDEA wrapping key verification pattern: ");
256 for(i = 0; i < 24; i++)
257 logmsg("%02X", sysblk.wkvpdea_reg[i]);
258 logmsg("\n");
259 #endif
260 }
261 #endif
262 #endif /* FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_3 */
263
264 #if !defined(_GEN_ARCH)
265
266 #if defined(_ARCHMODE2)
267 #define _GEN_ARCH _ARCHMODE2
268 #include "crypto.c"
269 #endif
270
271 #if defined(_ARCHMODE3)
272 #undef _GEN_ARCH
273 #define _GEN_ARCH _ARCHMODE3
274 #include "crypto.c"
275 #endif
276
277 #endif /*!defined(_GEN_ARCH)*/
278