diff options
Diffstat (limited to 'arch/s390/crypto/crypt_s390.h')
-rw-r--r-- | arch/s390/crypto/crypt_s390.h | 112 |
1 files changed, 108 insertions, 4 deletions
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 0ef9829f2ad6..49676771bd66 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h | |||
@@ -24,13 +24,18 @@ | |||
24 | #define CRYPT_S390_PRIORITY 300 | 24 | #define CRYPT_S390_PRIORITY 300 |
25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 | 25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 |
26 | 26 | ||
27 | #define CRYPT_S390_MSA 0x1 | ||
28 | #define CRYPT_S390_MSA3 0x2 | ||
29 | #define CRYPT_S390_MSA4 0x4 | ||
30 | |||
27 | /* s390 cryptographic operations */ | 31 | /* s390 cryptographic operations */ |
28 | enum crypt_s390_operations { | 32 | enum crypt_s390_operations { |
29 | CRYPT_S390_KM = 0x0100, | 33 | CRYPT_S390_KM = 0x0100, |
30 | CRYPT_S390_KMC = 0x0200, | 34 | CRYPT_S390_KMC = 0x0200, |
31 | CRYPT_S390_KIMD = 0x0300, | 35 | CRYPT_S390_KIMD = 0x0300, |
32 | CRYPT_S390_KLMD = 0x0400, | 36 | CRYPT_S390_KLMD = 0x0400, |
33 | CRYPT_S390_KMAC = 0x0500 | 37 | CRYPT_S390_KMAC = 0x0500, |
38 | CRYPT_S390_KMCTR = 0x0600 | ||
34 | }; | 39 | }; |
35 | 40 | ||
36 | /* | 41 | /* |
@@ -51,6 +56,10 @@ enum crypt_s390_km_func { | |||
51 | KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, | 56 | KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, |
52 | KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, | 57 | KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, |
53 | KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, | 58 | KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, |
59 | KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32, | ||
60 | KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80, | ||
61 | KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34, | ||
62 | KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80, | ||
54 | }; | 63 | }; |
55 | 64 | ||
56 | /* | 65 | /* |
@@ -75,6 +84,26 @@ enum crypt_s390_kmc_func { | |||
75 | }; | 84 | }; |
76 | 85 | ||
77 | /* | 86 | /* |
87 | * function codes for KMCTR (CIPHER MESSAGE WITH COUNTER) | ||
88 | * instruction | ||
89 | */ | ||
90 | enum crypt_s390_kmctr_func { | ||
91 | KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0, | ||
92 | KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1, | ||
93 | KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80, | ||
94 | KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2, | ||
95 | KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80, | ||
96 | KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3, | ||
97 | KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80, | ||
98 | KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12, | ||
99 | KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80, | ||
100 | KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13, | ||
101 | KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80, | ||
102 | KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14, | ||
103 | KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80, | ||
104 | }; | ||
105 | |||
106 | /* | ||
78 | * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) | 107 | * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) |
79 | * instruction | 108 | * instruction |
80 | */ | 109 | */ |
@@ -83,6 +112,7 @@ enum crypt_s390_kimd_func { | |||
83 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, | 112 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, |
84 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, | 113 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, |
85 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, | 114 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, |
115 | KIMD_GHASH = CRYPT_S390_KIMD | 65, | ||
86 | }; | 116 | }; |
87 | 117 | ||
88 | /* | 118 | /* |
@@ -284,6 +314,45 @@ static inline int crypt_s390_kmac(long func, void *param, | |||
284 | } | 314 | } |
285 | 315 | ||
286 | /** | 316 | /** |
317 | * crypt_s390_kmctr: | ||
318 | * @func: the function code passed to KMCTR; see crypt_s390_kmctr_func | ||
319 | * @param: address of parameter block; see POP for details on each func | ||
320 | * @dest: address of destination memory area | ||
321 | * @src: address of source memory area | ||
322 | * @src_len: length of src operand in bytes | ||
323 | * @counter: address of counter value | ||
324 | * | ||
325 | * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU. | ||
326 | * | ||
327 | * Returns -1 for failure, 0 for the query func, number of processed | ||
328 | * bytes for encryption/decryption funcs | ||
329 | */ | ||
330 | static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, | ||
331 | const u8 *src, long src_len, u8 *counter) | ||
332 | { | ||
333 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; | ||
334 | register void *__param asm("1") = param; | ||
335 | register const u8 *__src asm("2") = src; | ||
336 | register long __src_len asm("3") = src_len; | ||
337 | register u8 *__dest asm("4") = dest; | ||
338 | register u8 *__ctr asm("6") = counter; | ||
339 | int ret = -1; | ||
340 | |||
341 | asm volatile( | ||
342 | "0: .insn rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */ | ||
343 | "1: brc 1,0b \n" /* handle partial completion */ | ||
344 | " la %0,0\n" | ||
345 | "2:\n" | ||
346 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | ||
347 | : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), | ||
348 | "+a" (__ctr) | ||
349 | : "d" (__func), "a" (__param) : "cc", "memory"); | ||
350 | if (ret < 0) | ||
351 | return ret; | ||
352 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | ||
353 | } | ||
354 | |||
355 | /** | ||
287 | * crypt_s390_func_available: | 356 | * crypt_s390_func_available: |
288 | * @func: the function code of the specific function; 0 if op in general | 357 | * @func: the function code of the specific function; 0 if op in general |
289 | * | 358 | * |
@@ -291,13 +360,17 @@ static inline int crypt_s390_kmac(long func, void *param, | |||
291 | * | 360 | * |
292 | * Returns 1 if func available; 0 if func or op in general not available | 361 | * Returns 1 if func available; 0 if func or op in general not available |
293 | */ | 362 | */ |
294 | static inline int crypt_s390_func_available(int func) | 363 | static inline int crypt_s390_func_available(int func, |
364 | unsigned int facility_mask) | ||
295 | { | 365 | { |
296 | unsigned char status[16]; | 366 | unsigned char status[16]; |
297 | int ret; | 367 | int ret; |
298 | 368 | ||
299 | /* check if CPACF facility (bit 17) is available */ | 369 | if (facility_mask & CRYPT_S390_MSA && !test_facility(17)) |
300 | if (!(stfl() & 1ULL << (31 - 17))) | 370 | return 0; |
371 | if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76)) | ||
372 | return 0; | ||
373 | if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) | ||
301 | return 0; | 374 | return 0; |
302 | 375 | ||
303 | switch (func & CRYPT_S390_OP_MASK) { | 376 | switch (func & CRYPT_S390_OP_MASK) { |
@@ -316,6 +389,10 @@ static inline int crypt_s390_func_available(int func) | |||
316 | case CRYPT_S390_KMAC: | 389 | case CRYPT_S390_KMAC: |
317 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); | 390 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); |
318 | break; | 391 | break; |
392 | case CRYPT_S390_KMCTR: | ||
393 | ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0, | ||
394 | NULL); | ||
395 | break; | ||
319 | default: | 396 | default: |
320 | return 0; | 397 | return 0; |
321 | } | 398 | } |
@@ -326,4 +403,31 @@ static inline int crypt_s390_func_available(int func) | |||
326 | return (status[func >> 3] & (0x80 >> (func & 7))) != 0; | 403 | return (status[func >> 3] & (0x80 >> (func & 7))) != 0; |
327 | } | 404 | } |
328 | 405 | ||
406 | /** | ||
407 | * crypt_s390_pcc: | ||
408 | * @func: the function code passed to KM; see crypt_s390_km_func | ||
409 | * @param: address of parameter block; see POP for details on each func | ||
410 | * | ||
411 | * Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU. | ||
412 | * | ||
413 | * Returns -1 for failure, 0 for success. | ||
414 | */ | ||
415 | static inline int crypt_s390_pcc(long func, void *param) | ||
416 | { | ||
417 | register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */ | ||
418 | register void *__param asm("1") = param; | ||
419 | int ret = -1; | ||
420 | |||
421 | asm volatile( | ||
422 | "0: .insn rre,0xb92c0000,0,0 \n" /* PCC opcode */ | ||
423 | "1: brc 1,0b \n" /* handle partial completion */ | ||
424 | " la %0,0\n" | ||
425 | "2:\n" | ||
426 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | ||
427 | : "+d" (ret) | ||
428 | : "d" (__func), "a" (__param) : "cc", "memory"); | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | |||
329 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ | 433 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ |