diff options
author | Harald Freudenberger <freude@linux.vnet.ibm.com> | 2015-03-16 09:52:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-04-23 10:56:21 -0400 |
commit | 57127645d79d2e83e801f141f7d03f64accf28aa (patch) | |
tree | 6503d13da57110c71442d8f0fd2740ea92fdc292 /arch/s390/crypto/crypt_s390.h | |
parent | a1c843b82541fdd4c4644607c942dabc7c7e6f6c (diff) |
s390/zcrypt: Introduce new SHA-512 based Pseudo Random Generator.
Rework of the prandom device with introduction of a new SHA-512 based
NIST SP 800-90 conform deterministic random bit generator.
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/crypto/crypt_s390.h')
-rw-r--r-- | arch/s390/crypto/crypt_s390.h | 122 |
1 files changed, 91 insertions, 31 deletions
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index ba3b2aefddf5..d9c4c313fbc6 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h | |||
@@ -3,9 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Support for s390 cryptographic instructions. | 4 | * Support for s390 cryptographic instructions. |
5 | * | 5 | * |
6 | * Copyright IBM Corp. 2003, 2007 | 6 | * Copyright IBM Corp. 2003, 2015 |
7 | * Author(s): Thomas Spatzier | 7 | * Author(s): Thomas Spatzier |
8 | * Jan Glauber (jan.glauber@de.ibm.com) | 8 | * Jan Glauber (jan.glauber@de.ibm.com) |
9 | * Harald Freudenberger (freude@de.ibm.com) | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
11 | * under the terms of the GNU General Public License as published by the Free | 12 | * under the terms of the GNU General Public License as published by the Free |
@@ -28,15 +29,17 @@ | |||
28 | #define CRYPT_S390_MSA 0x1 | 29 | #define CRYPT_S390_MSA 0x1 |
29 | #define CRYPT_S390_MSA3 0x2 | 30 | #define CRYPT_S390_MSA3 0x2 |
30 | #define CRYPT_S390_MSA4 0x4 | 31 | #define CRYPT_S390_MSA4 0x4 |
32 | #define CRYPT_S390_MSA5 0x8 | ||
31 | 33 | ||
32 | /* s390 cryptographic operations */ | 34 | /* s390 cryptographic operations */ |
33 | enum crypt_s390_operations { | 35 | enum crypt_s390_operations { |
34 | CRYPT_S390_KM = 0x0100, | 36 | CRYPT_S390_KM = 0x0100, |
35 | CRYPT_S390_KMC = 0x0200, | 37 | CRYPT_S390_KMC = 0x0200, |
36 | CRYPT_S390_KIMD = 0x0300, | 38 | CRYPT_S390_KIMD = 0x0300, |
37 | CRYPT_S390_KLMD = 0x0400, | 39 | CRYPT_S390_KLMD = 0x0400, |
38 | CRYPT_S390_KMAC = 0x0500, | 40 | CRYPT_S390_KMAC = 0x0500, |
39 | CRYPT_S390_KMCTR = 0x0600 | 41 | CRYPT_S390_KMCTR = 0x0600, |
42 | CRYPT_S390_PPNO = 0x0700 | ||
40 | }; | 43 | }; |
41 | 44 | ||
42 | /* | 45 | /* |
@@ -138,6 +141,16 @@ enum crypt_s390_kmac_func { | |||
138 | KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 | 141 | KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 |
139 | }; | 142 | }; |
140 | 143 | ||
144 | /* | ||
145 | * function codes for PPNO (PERFORM PSEUDORANDOM NUMBER | ||
146 | * OPERATION) instruction | ||
147 | */ | ||
148 | enum crypt_s390_ppno_func { | ||
149 | PPNO_QUERY = CRYPT_S390_PPNO | 0, | ||
150 | PPNO_SHA512_DRNG_GEN = CRYPT_S390_PPNO | 3, | ||
151 | PPNO_SHA512_DRNG_SEED = CRYPT_S390_PPNO | 0x83 | ||
152 | }; | ||
153 | |||
141 | /** | 154 | /** |
142 | * crypt_s390_km: | 155 | * crypt_s390_km: |
143 | * @func: the function code passed to KM; see crypt_s390_km_func | 156 | * @func: the function code passed to KM; see crypt_s390_km_func |
@@ -162,11 +175,11 @@ static inline int crypt_s390_km(long func, void *param, | |||
162 | int ret; | 175 | int ret; |
163 | 176 | ||
164 | asm volatile( | 177 | asm volatile( |
165 | "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ | 178 | "0: .insn rre,0xb92e0000,%3,%1\n" /* KM opcode */ |
166 | "1: brc 1,0b \n" /* handle partial completion */ | 179 | "1: brc 1,0b\n" /* handle partial completion */ |
167 | " la %0,0\n" | 180 | " la %0,0\n" |
168 | "2:\n" | 181 | "2:\n" |
169 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 182 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
170 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) | 183 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) |
171 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); | 184 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
172 | if (ret < 0) | 185 | if (ret < 0) |
@@ -198,11 +211,11 @@ static inline int crypt_s390_kmc(long func, void *param, | |||
198 | int ret; | 211 | int ret; |
199 | 212 | ||
200 | asm volatile( | 213 | asm volatile( |
201 | "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ | 214 | "0: .insn rre,0xb92f0000,%3,%1\n" /* KMC opcode */ |
202 | "1: brc 1,0b \n" /* handle partial completion */ | 215 | "1: brc 1,0b\n" /* handle partial completion */ |
203 | " la %0,0\n" | 216 | " la %0,0\n" |
204 | "2:\n" | 217 | "2:\n" |
205 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 218 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
206 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) | 219 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) |
207 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); | 220 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
208 | if (ret < 0) | 221 | if (ret < 0) |
@@ -233,11 +246,11 @@ static inline int crypt_s390_kimd(long func, void *param, | |||
233 | int ret; | 246 | int ret; |
234 | 247 | ||
235 | asm volatile( | 248 | asm volatile( |
236 | "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ | 249 | "0: .insn rre,0xb93e0000,%1,%1\n" /* KIMD opcode */ |
237 | "1: brc 1,0b \n" /* handle partial completion */ | 250 | "1: brc 1,0b\n" /* handle partial completion */ |
238 | " la %0,0\n" | 251 | " la %0,0\n" |
239 | "2:\n" | 252 | "2:\n" |
240 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 253 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
241 | : "=d" (ret), "+a" (__src), "+d" (__src_len) | 254 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
242 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); | 255 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
243 | if (ret < 0) | 256 | if (ret < 0) |
@@ -267,11 +280,11 @@ static inline int crypt_s390_klmd(long func, void *param, | |||
267 | int ret; | 280 | int ret; |
268 | 281 | ||
269 | asm volatile( | 282 | asm volatile( |
270 | "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ | 283 | "0: .insn rre,0xb93f0000,%1,%1\n" /* KLMD opcode */ |
271 | "1: brc 1,0b \n" /* handle partial completion */ | 284 | "1: brc 1,0b\n" /* handle partial completion */ |
272 | " la %0,0\n" | 285 | " la %0,0\n" |
273 | "2:\n" | 286 | "2:\n" |
274 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 287 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
275 | : "=d" (ret), "+a" (__src), "+d" (__src_len) | 288 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
276 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); | 289 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
277 | if (ret < 0) | 290 | if (ret < 0) |
@@ -302,11 +315,11 @@ static inline int crypt_s390_kmac(long func, void *param, | |||
302 | int ret; | 315 | int ret; |
303 | 316 | ||
304 | asm volatile( | 317 | asm volatile( |
305 | "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ | 318 | "0: .insn rre,0xb91e0000,%1,%1\n" /* KLAC opcode */ |
306 | "1: brc 1,0b \n" /* handle partial completion */ | 319 | "1: brc 1,0b\n" /* handle partial completion */ |
307 | " la %0,0\n" | 320 | " la %0,0\n" |
308 | "2:\n" | 321 | "2:\n" |
309 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 322 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
310 | : "=d" (ret), "+a" (__src), "+d" (__src_len) | 323 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
311 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); | 324 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
312 | if (ret < 0) | 325 | if (ret < 0) |
@@ -340,11 +353,11 @@ static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, | |||
340 | int ret = -1; | 353 | int ret = -1; |
341 | 354 | ||
342 | asm volatile( | 355 | asm volatile( |
343 | "0: .insn rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */ | 356 | "0: .insn rrf,0xb92d0000,%3,%1,%4,0\n" /* KMCTR opcode */ |
344 | "1: brc 1,0b \n" /* handle partial completion */ | 357 | "1: brc 1,0b\n" /* handle partial completion */ |
345 | " la %0,0\n" | 358 | " la %0,0\n" |
346 | "2:\n" | 359 | "2:\n" |
347 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 360 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
348 | : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), | 361 | : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), |
349 | "+a" (__ctr) | 362 | "+a" (__ctr) |
350 | : "d" (__func), "a" (__param) : "cc", "memory"); | 363 | : "d" (__func), "a" (__param) : "cc", "memory"); |
@@ -354,6 +367,47 @@ static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, | |||
354 | } | 367 | } |
355 | 368 | ||
356 | /** | 369 | /** |
370 | * crypt_s390_ppno: | ||
371 | * @func: the function code passed to PPNO; see crypt_s390_ppno_func | ||
372 | * @param: address of parameter block; see POP for details on each func | ||
373 | * @dest: address of destination memory area | ||
374 | * @dest_len: size of destination memory area in bytes | ||
375 | * @seed: address of seed data | ||
376 | * @seed_len: size of seed data in bytes | ||
377 | * | ||
378 | * Executes the PPNO (PERFORM PSEUDORANDOM NUMBER OPERATION) | ||
379 | * operation of the CPU. | ||
380 | * | ||
381 | * Returns -1 for failure, 0 for the query func, number of random | ||
382 | * bytes stored in dest buffer for generate function | ||
383 | */ | ||
384 | static inline int crypt_s390_ppno(long func, void *param, | ||
385 | u8 *dest, long dest_len, | ||
386 | const u8 *seed, long seed_len) | ||
387 | { | ||
388 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; | ||
389 | register void *__param asm("1") = param; /* param block (240 bytes) */ | ||
390 | register u8 *__dest asm("2") = dest; /* buf for recv random bytes */ | ||
391 | register long __dest_len asm("3") = dest_len; /* requested random bytes */ | ||
392 | register const u8 *__seed asm("4") = seed; /* buf with seed data */ | ||
393 | register long __seed_len asm("5") = seed_len; /* bytes in seed buf */ | ||
394 | int ret = -1; | ||
395 | |||
396 | asm volatile ( | ||
397 | "0: .insn rre,0xb93c0000,%1,%5\n" /* PPNO opcode */ | ||
398 | "1: brc 1,0b\n" /* handle partial completion */ | ||
399 | " la %0,0\n" | ||
400 | "2:\n" | ||
401 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | ||
402 | : "+d" (ret), "+a"(__dest), "+d"(__dest_len) | ||
403 | : "d"(__func), "a"(__param), "a"(__seed), "d"(__seed_len) | ||
404 | : "cc", "memory"); | ||
405 | if (ret < 0) | ||
406 | return ret; | ||
407 | return (func & CRYPT_S390_FUNC_MASK) ? dest_len - __dest_len : 0; | ||
408 | } | ||
409 | |||
410 | /** | ||
357 | * crypt_s390_func_available: | 411 | * crypt_s390_func_available: |
358 | * @func: the function code of the specific function; 0 if op in general | 412 | * @func: the function code of the specific function; 0 if op in general |
359 | * | 413 | * |
@@ -373,6 +427,9 @@ static inline int crypt_s390_func_available(int func, | |||
373 | return 0; | 427 | return 0; |
374 | if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) | 428 | if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) |
375 | return 0; | 429 | return 0; |
430 | if (facility_mask & CRYPT_S390_MSA5 && !test_facility(57)) | ||
431 | return 0; | ||
432 | |||
376 | switch (func & CRYPT_S390_OP_MASK) { | 433 | switch (func & CRYPT_S390_OP_MASK) { |
377 | case CRYPT_S390_KM: | 434 | case CRYPT_S390_KM: |
378 | ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); | 435 | ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); |
@@ -390,8 +447,12 @@ static inline int crypt_s390_func_available(int func, | |||
390 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); | 447 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); |
391 | break; | 448 | break; |
392 | case CRYPT_S390_KMCTR: | 449 | case CRYPT_S390_KMCTR: |
393 | ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0, | 450 | ret = crypt_s390_kmctr(KMCTR_QUERY, &status, |
394 | NULL); | 451 | NULL, NULL, 0, NULL); |
452 | break; | ||
453 | case CRYPT_S390_PPNO: | ||
454 | ret = crypt_s390_ppno(PPNO_QUERY, &status, | ||
455 | NULL, 0, NULL, 0); | ||
395 | break; | 456 | break; |
396 | default: | 457 | default: |
397 | return 0; | 458 | return 0; |
@@ -419,15 +480,14 @@ static inline int crypt_s390_pcc(long func, void *param) | |||
419 | int ret = -1; | 480 | int ret = -1; |
420 | 481 | ||
421 | asm volatile( | 482 | asm volatile( |
422 | "0: .insn rre,0xb92c0000,0,0 \n" /* PCC opcode */ | 483 | "0: .insn rre,0xb92c0000,0,0\n" /* PCC opcode */ |
423 | "1: brc 1,0b \n" /* handle partial completion */ | 484 | "1: brc 1,0b\n" /* handle partial completion */ |
424 | " la %0,0\n" | 485 | " la %0,0\n" |
425 | "2:\n" | 486 | "2:\n" |
426 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | 487 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
427 | : "+d" (ret) | 488 | : "+d" (ret) |
428 | : "d" (__func), "a" (__param) : "cc", "memory"); | 489 | : "d" (__func), "a" (__param) : "cc", "memory"); |
429 | return ret; | 490 | return ret; |
430 | } | 491 | } |
431 | 492 | ||
432 | |||
433 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ | 493 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ |