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