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/* s930 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}; 86 87/* 88 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) 89 * instruction 90 */ 91enum crypt_s390_klmd_func { 92 KLMD_QUERY = CRYPT_S390_KLMD | 0, 93 KLMD_SHA_1 = CRYPT_S390_KLMD | 1, 94 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 95}; 96 97/* 98 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 99 * instruction 100 */ 101enum crypt_s390_kmac_func { 102 KMAC_QUERY = CRYPT_S390_KMAC | 0, 103 KMAC_DEA = CRYPT_S390_KMAC | 1, 104 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2, 105 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 106}; 107 108/** 109 * crypt_s390_km: 110 * @func: the function code passed to KM; see crypt_s390_km_func 111 * @param: address of parameter block; see POP for details on each func 112 * @dest: address of destination memory area 113 * @src: address of source memory area 114 * @src_len: length of src operand in bytes 115 * 116 * Executes the KM (CIPHER MESSAGE) operation of the CPU. 117 * 118 * Returns -1 for failure, 0 for the query func, number of processed 119 * bytes for encryption/decryption funcs 120 */ 121static inline int crypt_s390_km(long func, void *param, 122 u8 *dest, const u8 *src, long src_len) 123{ 124 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 125 register void *__param asm("1") = param; 126 register const u8 *__src asm("2") = src; 127 register long __src_len asm("3") = src_len; 128 register u8 *__dest asm("4") = dest; 129 int ret; 130 131 asm volatile( 132 "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ 133 "1: brc 1,0b \n" /* handle partial completion */ 134 " la %0,0\n" 135 "2:\n" 136 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 137 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 138 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 139 if (ret < 0) 140 return ret; 141 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 142} 143 144/** 145 * crypt_s390_kmc: 146 * @func: the function code passed to KM; see crypt_s390_kmc_func 147 * @param: address of parameter block; see POP for details on each func 148 * @dest: address of destination memory area 149 * @src: address of source memory area 150 * @src_len: length of src operand in bytes 151 * 152 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. 153 * 154 * Returns -1 for failure, 0 for the query func, number of processed 155 * bytes for encryption/decryption funcs 156 */ 157static inline int crypt_s390_kmc(long func, void *param, 158 u8 *dest, const u8 *src, long src_len) 159{ 160 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 161 register void *__param asm("1") = param; 162 register const u8 *__src asm("2") = src; 163 register long __src_len asm("3") = src_len; 164 register u8 *__dest asm("4") = dest; 165 int ret; 166 167 asm volatile( 168 "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ 169 "1: brc 1,0b \n" /* handle partial completion */ 170 " la %0,0\n" 171 "2:\n" 172 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 173 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 174 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 175 if (ret < 0) 176 return ret; 177 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 178} 179 180/** 181 * crypt_s390_kimd: 182 * @func: the function code passed to KM; see crypt_s390_kimd_func 183 * @param: address of parameter block; see POP for details on each func 184 * @src: address of source memory area 185 * @src_len: length of src operand in bytes 186 * 187 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 188 * of the CPU. 189 * 190 * Returns -1 for failure, 0 for the query func, number of processed 191 * bytes for digest funcs 192 */ 193static inline int crypt_s390_kimd(long func, void *param, 194 const u8 *src, long src_len) 195{ 196 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 197 register void *__param asm("1") = param; 198 register const u8 *__src asm("2") = src; 199 register long __src_len asm("3") = src_len; 200 int ret; 201 202 asm volatile( 203 "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ 204 "1: brc 1,0b \n" /* handle partial completion */ 205 " la %0,0\n" 206 "2:\n" 207 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 208 : "=d" (ret), "+a" (__src), "+d" (__src_len) 209 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 210 if (ret < 0) 211 return ret; 212 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 213} 214 215/** 216 * crypt_s390_klmd: 217 * @func: the function code passed to KM; see crypt_s390_klmd_func 218 * @param: address of parameter block; see POP for details on each func 219 * @src: address of source memory area 220 * @src_len: length of src operand in bytes 221 * 222 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. 223 * 224 * Returns -1 for failure, 0 for the query func, number of processed 225 * bytes for digest funcs 226 */ 227static inline int crypt_s390_klmd(long func, void *param, 228 const u8 *src, long src_len) 229{ 230 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 231 register void *__param asm("1") = param; 232 register const u8 *__src asm("2") = src; 233 register long __src_len asm("3") = src_len; 234 int ret; 235 236 asm volatile( 237 "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ 238 "1: brc 1,0b \n" /* handle partial completion */ 239 " la %0,0\n" 240 "2:\n" 241 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 242 : "=d" (ret), "+a" (__src), "+d" (__src_len) 243 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 244 if (ret < 0) 245 return ret; 246 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 247} 248 249/** 250 * crypt_s390_kmac: 251 * @func: the function code passed to KM; see crypt_s390_klmd_func 252 * @param: address of parameter block; see POP for details on each func 253 * @src: address of source memory area 254 * @src_len: length of src operand in bytes 255 * 256 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 257 * of the CPU. 258 * 259 * Returns -1 for failure, 0 for the query func, number of processed 260 * bytes for digest funcs 261 */ 262static inline int crypt_s390_kmac(long func, void *param, 263 const u8 *src, long src_len) 264{ 265 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 266 register void *__param asm("1") = param; 267 register const u8 *__src asm("2") = src; 268 register long __src_len asm("3") = src_len; 269 int ret; 270 271 asm volatile( 272 "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ 273 "1: brc 1,0b \n" /* handle partial completion */ 274 " la %0,0\n" 275 "2:\n" 276 EX_TABLE(0b,2b) EX_TABLE(1b,2b) 277 : "=d" (ret), "+a" (__src), "+d" (__src_len) 278 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); 279 if (ret < 0) 280 return ret; 281 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 282} 283 284/** 285 * crypt_s390_func_available: 286 * @func: the function code of the specific function; 0 if op in general 287 * 288 * Tests if a specific crypto function is implemented on the machine. 289 * 290 * Returns 1 if func available; 0 if func or op in general not available 291 */ 292static inline int crypt_s390_func_available(int func) 293{ 294 unsigned char status[16]; 295 int ret; 296 297 switch (func & CRYPT_S390_OP_MASK) { 298 case CRYPT_S390_KM: 299 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); 300 break; 301 case CRYPT_S390_KMC: 302 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); 303 break; 304 case CRYPT_S390_KIMD: 305 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); 306 break; 307 case CRYPT_S390_KLMD: 308 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); 309 break; 310 case CRYPT_S390_KMAC: 311 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); 312 break; 313 default: 314 return 0; 315 } 316 if (ret < 0) 317 return 0; 318 func &= CRYPT_S390_FUNC_MASK; 319 func &= 0x7f; /* mask modifier bit */ 320 return (status[func >> 3] & (0x80 >> (func & 7))) != 0; 321} 322 323#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ 324