diff options
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 */ |
