1/* 2 * Cryptographic API. 3 * 4 * Support for s390 cryptographic instructions. 5 * 6 * Copyright IBM Corp. 2003,2007 7 * Author(s): Thomas Spatzier 8 * Jan Glauber (jan.glauber@de.ibm.com) 9 * 10 * 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 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 * 15 */ 16#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H 17#define _CRYPTO_ARCH_S390_CRYPT_S390_H 18 19#include <asm/errno.h> 20 21#define CRYPT_S390_OP_MASK 0xFF00 22#define CRYPT_S390_FUNC_MASK 0x00FF 23 24#define CRYPT_S390_PRIORITY 300 25#define CRYPT_S390_COMPOSITE_PRIORITY 400 26 27/* s390 cryptographic operations */ 28enum crypt_s390_operations { 29 CRYPT_S390_KM = 0x0100, 30 CRYPT_S390_KMC = 0x0200, 31 CRYPT_S390_KIMD = 0x0300, 32 CRYPT_S390_KLMD = 0x0400, 33 CRYPT_S390_KMAC = 0x0500 34}; 35 36/* 37 * function codes for KM (CIPHER MESSAGE) instruction 38 * 0x80 is the decipher modifier bit 39 */ 40enum crypt_s390_km_func { 41 KM_QUERY = CRYPT_S390_KM | 0x0, 42 KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1, 43 KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80, 44 KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2, 45 KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80, 46 KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3, 47 KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80, 48 KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12, 49 KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80, 50 KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13, 51 KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, 52 KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, 53 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, 54}; 55 56/* 57 * function codes for KMC (CIPHER MESSAGE WITH CHAINING) 58 * instruction 59 */ 60enum crypt_s390_kmc_func { 61 KMC_QUERY = CRYPT_S390_KMC | 0x0, 62 KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1, 63 KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80, 64 KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2, 65 KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80, 66 KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3, 67 KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80, 68 KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12, 69 KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80, 70 KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13, 71 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80, 72 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14, 73 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80, 74 KMC_PRNG = CRYPT_S390_KMC | 0x43, 75}; 76 77/* 78 * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 79 * instruction 80 */ 81enum crypt_s390_kimd_func { 82 KIMD_QUERY = CRYPT_S390_KIMD | 0, 83 KIMD_SHA_1 = CRYPT_S390_KIMD | 1, 84 KIMD_SHA_256 = CRYPT_S390_KIMD | 2, 85 KIMD_SHA_512 = CRYPT_S390_KIMD | 3, 86}; 87 88/* 89 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) 90 * instruction 91 */ 92enum crypt_s390_klmd_func { 93 KLMD_QUERY = CRYPT_S390_KLMD | 0, 94 KLMD_SHA_1 = CRYPT_S390_KLMD | 1, 95 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 96 KLMD_SHA_512 = CRYPT_S390_KLMD | 3, 97}; 98 99/* 100 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 101 * instruction 102 */ 103enum crypt_s390_kmac_func { 104 KMAC_QUERY = CRYPT_S390_KMAC | 0, 105 KMAC_DEA = CRYPT_S390_KMAC | 1, 106 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2, 107 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 108}; 109 110/** 111 * crypt_s390_km: 112 * @func: the function code passed to KM; see crypt_s390_km_func 113 * @param: address of parameter block; see POP for details on each func 114 * @dest: address of destination memory area 115 * @src: address of source memory area 116 * @src_len: length of src operand in bytes 117 * 118 * Executes the KM (CIPHER MESSAGE) operation of the CPU. 119 * 120 * Returns -1 for failure, 0 for the query func, number of processed 121 * bytes for encryption/decryption funcs 122 */ 123static inline int crypt_s390_km(long func, void *param, 124 u8 *dest, const u8 *src, long src_len) 125{ 126 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 127 register void *__param asm("1") = param; 128 register const u8 *__src asm("2") = src; 129 register long __src_len asm("3") = src_len; 130 register u8 *__dest asm("4") = dest; 131 int ret; 132 133 asm volatile( 134 "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ 135 "1: brc 1,0b \n" /* handle partial completion */ 136 " la %0,0\n" 137 "2:\n" 138 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 139 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 140 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 141 if (ret < 0) 142 return ret; 143 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 144} 145 146/** 147 * crypt_s390_kmc: 148 * @func: the function code passed to KM; see crypt_s390_kmc_func 149 * @param: address of parameter block; see POP for details on each func 150 * @dest: address of destination memory area 151 * @src: address of source memory area 152 * @src_len: length of src operand in bytes 153 * 154 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. 155 * 156 * Returns -1 for failure, 0 for the query func, number of processed 157 * bytes for encryption/decryption funcs 158 */ 159static inline int crypt_s390_kmc(long func, void *param, 160 u8 *dest, const u8 *src, long src_len) 161{ 162 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 163 register void *__param asm("1") = param; 164 register const u8 *__src asm("2") = src; 165 register long __src_len asm("3") = src_len; 166 register u8 *__dest asm("4") = dest; 167 int ret; 168 169 asm volatile( 170 "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ 171 "1: brc 1,0b \n" /* handle partial completion */ 172 " la %0,0\n" 173 "2:\n" 174 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 175 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 176 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 177 if (ret < 0) 178 return ret; 179 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 180} 181 182/** 183 * crypt_s390_kimd: 184 * @func: the function code passed to KM; see crypt_s390_kimd_func 185 * @param: address of parameter block; see POP for details on each func 186 * @src: address of source memory area 187 * @src_len: length of src operand in bytes 188 * 189 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 190 * of the CPU. 191 * 192 * Returns -1 for failure, 0 for the query func, number of processed 193 * bytes for digest funcs 194 */ 195static inline int crypt_s390_kimd(long func, void *param, 196 const u8 *src, long src_len) 197{ 198 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 199 register void *__param asm("1") = param; 200 register const u8 *__src asm("2") = src; 201 register long __src_len asm("3") = src_len; 202 int ret; 203 204 asm volatile( 205 "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ 206 "1: brc 1,0b \n" /* handle partial completion */ 207 " la %0,0\n" 208 "2:\n" 209 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 210 : "=d" (ret), "+a" (__src), "+d" (__src_len) 211 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 212 if (ret < 0) 213 return ret; 214 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 215} 216 217/** 218 * crypt_s390_klmd: 219 * @func: the function code passed to KM; see crypt_s390_klmd_func 220 * @param: address of parameter block; see POP for details on each func 221 * @src: address of source memory area 222 * @src_len: length of src operand in bytes 223 * 224 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. 225 * 226 * Returns -1 for failure, 0 for the query func, number of processed 227 * bytes for digest funcs 228 */ 229static inline int crypt_s390_klmd(long func, void *param, 230 const u8 *src, long src_len) 231{ 232 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 233 register void *__param asm("1") = param; 234 register const u8 *__src asm("2") = src; 235 register long __src_len asm("3") = src_len; 236 int ret; 237 238 asm volatile( 239 "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ 240 "1: brc 1,0b \n" /* handle partial completion */ 241 " la %0,0\n" 242 "2:\n" 243 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 244 : "=d" (ret), "+a" (__src), "+d" (__src_len) 245 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 246 if (ret < 0) 247 return ret; 248 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 249} 250 251/** 252 * crypt_s390_kmac: 253 * @func: the function code passed to KM; see crypt_s390_klmd_func 254 * @param: address of parameter block; see POP for details on each func 255 * @src: address of source memory area 256 * @src_len: length of src operand in bytes 257 * 258 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 259 * of the CPU. 260 * 261 * Returns -1 for failure, 0 for the query func, number of processed 262 * bytes for digest funcs 263 */ 264static inline int crypt_s390_kmac(long func, void *param, 265 const u8 *src, long src_len) 266{ 267 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 268 register void *__param asm("1") = param; 269 register const u8 *__src asm("2") = src; 270 register long __src_len asm("3") = src_len; 271 int ret; 272 273 asm volatile( 274 "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ 275 "1: brc 1,0b \n" /* handle partial completion */ 276 " la %0,0\n" 277 "2:\n" 278 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 279 : "=d" (ret), "+a" (__src), "+d" (__src_len) 280 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 281 if (ret < 0) 282 return ret; 283 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 284} 285 286/** 287 * crypt_s390_func_available: 288 * @func: the function code of the specific function; 0 if op in general 289 * 290 * Tests if a specific crypto function is implemented on the machine. 291 * 292 * Returns 1 if func available; 0 if func or op in general not available 293 */ 294static inline int crypt_s390_func_available(int func) 295{ 296 unsigned char status[16]; 297 int ret; 298 299 /* check if CPACF facility (bit 17) is available */ 300 if (!(stfl() & 1ULL << (31 - 17))) 301 return 0; 302 303 switch (func & CRYPT_S390_OP_MASK) { 304 case CRYPT_S390_KM: 305 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); 306 break; 307 case CRYPT_S390_KMC: 308 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); 309 break; 310 case CRYPT_S390_KIMD: 311 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); 312 break; 313 case CRYPT_S390_KLMD: 314 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); 315 break; 316 case CRYPT_S390_KMAC: 317 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); 318 break; 319 default: 320 return 0; 321 } 322 if (ret < 0) 323 return 0; 324 func &= CRYPT_S390_FUNC_MASK; 325 func &= 0x7f; /* mask modifier bit */ 326 return (status[func >> 3] & (0x80 >> (func & 7))) != 0; 327} 328 329#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ 330