1/* 2 * Cryptographic API. 3 * 4 * Support for s390 cryptographic instructions. 5 * 6 * Copyright IBM Corp. 2003, 2015 7 * Author(s): Thomas Spatzier 8 * Jan Glauber (jan.glauber@de.ibm.com) 9 * Harald Freudenberger (freude@de.ibm.com) 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the Free 13 * Software Foundation; either version 2 of the License, or (at your option) 14 * any later version. 15 * 16 */ 17#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H 18#define _CRYPTO_ARCH_S390_CRYPT_S390_H 19 20#include <asm/errno.h> 21#include <asm/facility.h> 22 23#define CRYPT_S390_OP_MASK 0xFF00 24#define CRYPT_S390_FUNC_MASK 0x00FF 25 26#define CRYPT_S390_PRIORITY 300 27#define CRYPT_S390_COMPOSITE_PRIORITY 400 28 29#define CRYPT_S390_MSA 0x1 30#define CRYPT_S390_MSA3 0x2 31#define CRYPT_S390_MSA4 0x4 32#define CRYPT_S390_MSA5 0x8 33 34/* s390 cryptographic operations */ 35enum crypt_s390_operations { 36 CRYPT_S390_KM = 0x0100, 37 CRYPT_S390_KMC = 0x0200, 38 CRYPT_S390_KIMD = 0x0300, 39 CRYPT_S390_KLMD = 0x0400, 40 CRYPT_S390_KMAC = 0x0500, 41 CRYPT_S390_KMCTR = 0x0600, 42 CRYPT_S390_PPNO = 0x0700 43}; 44 45/* 46 * function codes for KM (CIPHER MESSAGE) instruction 47 * 0x80 is the decipher modifier bit 48 */ 49enum crypt_s390_km_func { 50 KM_QUERY = CRYPT_S390_KM | 0x0, 51 KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1, 52 KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80, 53 KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2, 54 KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80, 55 KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3, 56 KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80, 57 KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12, 58 KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80, 59 KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13, 60 KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, 61 KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, 62 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, 63 KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32, 64 KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80, 65 KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34, 66 KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80, 67}; 68 69/* 70 * function codes for KMC (CIPHER MESSAGE WITH CHAINING) 71 * instruction 72 */ 73enum crypt_s390_kmc_func { 74 KMC_QUERY = CRYPT_S390_KMC | 0x0, 75 KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1, 76 KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80, 77 KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2, 78 KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80, 79 KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3, 80 KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80, 81 KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12, 82 KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80, 83 KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13, 84 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80, 85 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14, 86 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80, 87 KMC_PRNG = CRYPT_S390_KMC | 0x43, 88}; 89 90/* 91 * function codes for KMCTR (CIPHER MESSAGE WITH COUNTER) 92 * instruction 93 */ 94enum crypt_s390_kmctr_func { 95 KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0, 96 KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1, 97 KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80, 98 KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2, 99 KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80, 100 KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3, 101 KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80, 102 KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12, 103 KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80, 104 KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13, 105 KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80, 106 KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14, 107 KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80, 108}; 109 110/* 111 * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 112 * instruction 113 */ 114enum crypt_s390_kimd_func { 115 KIMD_QUERY = CRYPT_S390_KIMD | 0, 116 KIMD_SHA_1 = CRYPT_S390_KIMD | 1, 117 KIMD_SHA_256 = CRYPT_S390_KIMD | 2, 118 KIMD_SHA_512 = CRYPT_S390_KIMD | 3, 119 KIMD_GHASH = CRYPT_S390_KIMD | 65, 120}; 121 122/* 123 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) 124 * instruction 125 */ 126enum crypt_s390_klmd_func { 127 KLMD_QUERY = CRYPT_S390_KLMD | 0, 128 KLMD_SHA_1 = CRYPT_S390_KLMD | 1, 129 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 130 KLMD_SHA_512 = CRYPT_S390_KLMD | 3, 131}; 132 133/* 134 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 135 * instruction 136 */ 137enum crypt_s390_kmac_func { 138 KMAC_QUERY = CRYPT_S390_KMAC | 0, 139 KMAC_DEA = CRYPT_S390_KMAC | 1, 140 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2, 141 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 142}; 143 144/* 145 * function codes for PPNO (PERFORM PSEUDORANDOM NUMBER 146 * OPERATION) instruction 147 */ 148enum 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 154/** 155 * crypt_s390_km: 156 * @func: the function code passed to KM; see crypt_s390_km_func 157 * @param: address of parameter block; see POP for details on each func 158 * @dest: address of destination memory area 159 * @src: address of source memory area 160 * @src_len: length of src operand in bytes 161 * 162 * Executes the KM (CIPHER MESSAGE) operation of the CPU. 163 * 164 * Returns -1 for failure, 0 for the query func, number of processed 165 * bytes for encryption/decryption funcs 166 */ 167static inline int crypt_s390_km(long func, void *param, 168 u8 *dest, const u8 *src, long src_len) 169{ 170 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 171 register void *__param asm("1") = param; 172 register const u8 *__src asm("2") = src; 173 register long __src_len asm("3") = src_len; 174 register u8 *__dest asm("4") = dest; 175 int ret; 176 177 asm volatile( 178 "0: .insn rre,0xb92e0000,%3,%1\n" /* KM opcode */ 179 "1: brc 1,0b\n" /* handle partial completion */ 180 " la %0,0\n" 181 "2:\n" 182 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 183 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 184 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 185 if (ret < 0) 186 return ret; 187 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 188} 189 190/** 191 * crypt_s390_kmc: 192 * @func: the function code passed to KM; see crypt_s390_kmc_func 193 * @param: address of parameter block; see POP for details on each func 194 * @dest: address of destination memory area 195 * @src: address of source memory area 196 * @src_len: length of src operand in bytes 197 * 198 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. 199 * 200 * Returns -1 for failure, 0 for the query func, number of processed 201 * bytes for encryption/decryption funcs 202 */ 203static inline int crypt_s390_kmc(long func, void *param, 204 u8 *dest, const u8 *src, long src_len) 205{ 206 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 207 register void *__param asm("1") = param; 208 register const u8 *__src asm("2") = src; 209 register long __src_len asm("3") = src_len; 210 register u8 *__dest asm("4") = dest; 211 int ret; 212 213 asm volatile( 214 "0: .insn rre,0xb92f0000,%3,%1\n" /* KMC opcode */ 215 "1: brc 1,0b\n" /* handle partial completion */ 216 " la %0,0\n" 217 "2:\n" 218 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 219 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 220 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 221 if (ret < 0) 222 return ret; 223 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 224} 225 226/** 227 * crypt_s390_kimd: 228 * @func: the function code passed to KM; see crypt_s390_kimd_func 229 * @param: address of parameter block; see POP for details on each func 230 * @src: address of source memory area 231 * @src_len: length of src operand in bytes 232 * 233 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 234 * of the CPU. 235 * 236 * Returns -1 for failure, 0 for the query func, number of processed 237 * bytes for digest funcs 238 */ 239static inline int crypt_s390_kimd(long func, void *param, 240 const u8 *src, long src_len) 241{ 242 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 243 register void *__param asm("1") = param; 244 register const u8 *__src asm("2") = src; 245 register long __src_len asm("3") = src_len; 246 int ret; 247 248 asm volatile( 249 "0: .insn rre,0xb93e0000,%1,%1\n" /* KIMD opcode */ 250 "1: brc 1,0b\n" /* handle partial completion */ 251 " la %0,0\n" 252 "2:\n" 253 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 254 : "=d" (ret), "+a" (__src), "+d" (__src_len) 255 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 256 if (ret < 0) 257 return ret; 258 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 259} 260 261/** 262 * crypt_s390_klmd: 263 * @func: the function code passed to KM; see crypt_s390_klmd_func 264 * @param: address of parameter block; see POP for details on each func 265 * @src: address of source memory area 266 * @src_len: length of src operand in bytes 267 * 268 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. 269 * 270 * Returns -1 for failure, 0 for the query func, number of processed 271 * bytes for digest funcs 272 */ 273static inline int crypt_s390_klmd(long func, void *param, 274 const u8 *src, long src_len) 275{ 276 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 277 register void *__param asm("1") = param; 278 register const u8 *__src asm("2") = src; 279 register long __src_len asm("3") = src_len; 280 int ret; 281 282 asm volatile( 283 "0: .insn rre,0xb93f0000,%1,%1\n" /* KLMD opcode */ 284 "1: brc 1,0b\n" /* handle partial completion */ 285 " la %0,0\n" 286 "2:\n" 287 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 288 : "=d" (ret), "+a" (__src), "+d" (__src_len) 289 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 290 if (ret < 0) 291 return ret; 292 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 293} 294 295/** 296 * crypt_s390_kmac: 297 * @func: the function code passed to KM; see crypt_s390_klmd_func 298 * @param: address of parameter block; see POP for details on each func 299 * @src: address of source memory area 300 * @src_len: length of src operand in bytes 301 * 302 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 303 * of the CPU. 304 * 305 * Returns -1 for failure, 0 for the query func, number of processed 306 * bytes for digest funcs 307 */ 308static inline int crypt_s390_kmac(long func, void *param, 309 const u8 *src, long src_len) 310{ 311 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 312 register void *__param asm("1") = param; 313 register const u8 *__src asm("2") = src; 314 register long __src_len asm("3") = src_len; 315 int ret; 316 317 asm volatile( 318 "0: .insn rre,0xb91e0000,%1,%1\n" /* KLAC opcode */ 319 "1: brc 1,0b\n" /* handle partial completion */ 320 " la %0,0\n" 321 "2:\n" 322 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 323 : "=d" (ret), "+a" (__src), "+d" (__src_len) 324 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 325 if (ret < 0) 326 return ret; 327 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 328} 329 330/** 331 * crypt_s390_kmctr: 332 * @func: the function code passed to KMCTR; see crypt_s390_kmctr_func 333 * @param: address of parameter block; see POP for details on each func 334 * @dest: address of destination memory area 335 * @src: address of source memory area 336 * @src_len: length of src operand in bytes 337 * @counter: address of counter value 338 * 339 * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU. 340 * 341 * Returns -1 for failure, 0 for the query func, number of processed 342 * bytes for encryption/decryption funcs 343 */ 344static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, 345 const u8 *src, long src_len, u8 *counter) 346{ 347 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 348 register void *__param asm("1") = param; 349 register const u8 *__src asm("2") = src; 350 register long __src_len asm("3") = src_len; 351 register u8 *__dest asm("4") = dest; 352 register u8 *__ctr asm("6") = counter; 353 int ret = -1; 354 355 asm volatile( 356 "0: .insn rrf,0xb92d0000,%3,%1,%4,0\n" /* KMCTR opcode */ 357 "1: brc 1,0b\n" /* handle partial completion */ 358 " la %0,0\n" 359 "2:\n" 360 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 361 : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), 362 "+a" (__ctr) 363 : "d" (__func), "a" (__param) : "cc", "memory"); 364 if (ret < 0) 365 return ret; 366 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 367} 368 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 */ 384static 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/** 411 * crypt_s390_func_available: 412 * @func: the function code of the specific function; 0 if op in general 413 * 414 * Tests if a specific crypto function is implemented on the machine. 415 * 416 * Returns 1 if func available; 0 if func or op in general not available 417 */ 418static inline int crypt_s390_func_available(int func, 419 unsigned int facility_mask) 420{ 421 unsigned char status[16]; 422 int ret; 423 424 if (facility_mask & CRYPT_S390_MSA && !test_facility(17)) 425 return 0; 426 if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76)) 427 return 0; 428 if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) 429 return 0; 430 if (facility_mask & CRYPT_S390_MSA5 && !test_facility(57)) 431 return 0; 432 433 switch (func & CRYPT_S390_OP_MASK) { 434 case CRYPT_S390_KM: 435 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); 436 break; 437 case CRYPT_S390_KMC: 438 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); 439 break; 440 case CRYPT_S390_KIMD: 441 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); 442 break; 443 case CRYPT_S390_KLMD: 444 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); 445 break; 446 case CRYPT_S390_KMAC: 447 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); 448 break; 449 case CRYPT_S390_KMCTR: 450 ret = crypt_s390_kmctr(KMCTR_QUERY, &status, 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); 456 break; 457 default: 458 return 0; 459 } 460 if (ret < 0) 461 return 0; 462 func &= CRYPT_S390_FUNC_MASK; 463 func &= 0x7f; /* mask modifier bit */ 464 return (status[func >> 3] & (0x80 >> (func & 7))) != 0; 465} 466 467/** 468 * crypt_s390_pcc: 469 * @func: the function code passed to KM; see crypt_s390_km_func 470 * @param: address of parameter block; see POP for details on each func 471 * 472 * Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU. 473 * 474 * Returns -1 for failure, 0 for success. 475 */ 476static inline int crypt_s390_pcc(long func, void *param) 477{ 478 register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */ 479 register void *__param asm("1") = param; 480 int ret = -1; 481 482 asm volatile( 483 "0: .insn rre,0xb92c0000,0,0\n" /* PCC opcode */ 484 "1: brc 1,0b\n" /* handle partial completion */ 485 " la %0,0\n" 486 "2:\n" 487 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) 488 : "+d" (ret) 489 : "d" (__func), "a" (__param) : "cc", "memory"); 490 return ret; 491} 492 493#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ 494