Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.17 397 lines 12 kB view raw
1/* 2 * Cryptographic API. 3 * 4 * Support for s390 cryptographic instructions. 5 * 6 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation 7 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the Free 11 * Software Foundation; either version 2 of the License, or (at your option) 12 * any later version. 13 * 14 */ 15#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H 16#define _CRYPTO_ARCH_S390_CRYPT_S390_H 17 18#include <asm/errno.h> 19 20#define CRYPT_S390_OP_MASK 0xFF00 21#define CRYPT_S390_FUNC_MASK 0x00FF 22 23/* s930 cryptographic operations */ 24enum crypt_s390_operations { 25 CRYPT_S390_KM = 0x0100, 26 CRYPT_S390_KMC = 0x0200, 27 CRYPT_S390_KIMD = 0x0300, 28 CRYPT_S390_KLMD = 0x0400, 29 CRYPT_S390_KMAC = 0x0500 30}; 31 32/* function codes for KM (CIPHER MESSAGE) instruction 33 * 0x80 is the decipher modifier bit 34 */ 35enum crypt_s390_km_func { 36 KM_QUERY = CRYPT_S390_KM | 0x0, 37 KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1, 38 KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80, 39 KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2, 40 KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80, 41 KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3, 42 KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80, 43 KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12, 44 KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80, 45 KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13, 46 KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, 47 KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, 48 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, 49}; 50 51/* function codes for KMC (CIPHER MESSAGE WITH CHAINING) 52 * instruction 53 */ 54enum crypt_s390_kmc_func { 55 KMC_QUERY = CRYPT_S390_KMC | 0x0, 56 KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1, 57 KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80, 58 KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2, 59 KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80, 60 KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3, 61 KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80, 62 KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12, 63 KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80, 64 KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13, 65 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80, 66 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14, 67 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80, 68}; 69 70/* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 71 * instruction 72 */ 73enum crypt_s390_kimd_func { 74 KIMD_QUERY = CRYPT_S390_KIMD | 0, 75 KIMD_SHA_1 = CRYPT_S390_KIMD | 1, 76 KIMD_SHA_256 = CRYPT_S390_KIMD | 2, 77}; 78 79/* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) 80 * instruction 81 */ 82enum crypt_s390_klmd_func { 83 KLMD_QUERY = CRYPT_S390_KLMD | 0, 84 KLMD_SHA_1 = CRYPT_S390_KLMD | 1, 85 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 86}; 87 88/* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 89 * instruction 90 */ 91enum crypt_s390_kmac_func { 92 KMAC_QUERY = CRYPT_S390_KMAC | 0, 93 KMAC_DEA = CRYPT_S390_KMAC | 1, 94 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2, 95 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 96}; 97 98/* status word for s390 crypto instructions' QUERY functions */ 99struct crypt_s390_query_status { 100 u64 high; 101 u64 low; 102}; 103 104/* 105 * Standard fixup and ex_table sections for crypt_s390 inline functions. 106 * label 0: the s390 crypto operation 107 * label 1: just after 1 to catch illegal operation exception 108 * (unsupported model) 109 * label 6: the return point after fixup 110 * label 7: set error value if exception _in_ crypto operation 111 * label 8: set error value if illegal operation exception 112 * [ret] is the variable to receive the error code 113 * [ERR] is the error code value 114 */ 115#ifndef CONFIG_64BIT 116#define __crypt_s390_fixup \ 117 ".section .fixup,\"ax\" \n" \ 118 "7: lhi %0,%h[e1] \n" \ 119 " bras 1,9f \n" \ 120 " .long 6b \n" \ 121 "8: lhi %0,%h[e2] \n" \ 122 " bras 1,9f \n" \ 123 " .long 6b \n" \ 124 "9: l 1,0(1) \n" \ 125 " br 1 \n" \ 126 ".previous \n" \ 127 ".section __ex_table,\"a\" \n" \ 128 " .align 4 \n" \ 129 " .long 0b,7b \n" \ 130 " .long 1b,8b \n" \ 131 ".previous" 132#else /* CONFIG_64BIT */ 133#define __crypt_s390_fixup \ 134 ".section .fixup,\"ax\" \n" \ 135 "7: lhi %0,%h[e1] \n" \ 136 " jg 6b \n" \ 137 "8: lhi %0,%h[e2] \n" \ 138 " jg 6b \n" \ 139 ".previous\n" \ 140 ".section __ex_table,\"a\" \n" \ 141 " .align 8 \n" \ 142 " .quad 0b,7b \n" \ 143 " .quad 1b,8b \n" \ 144 ".previous" 145#endif /* CONFIG_64BIT */ 146 147/* 148 * Standard code for setting the result of s390 crypto instructions. 149 * %0: the register which will receive the result 150 * [result]: the register containing the result (e.g. second operand length 151 * to compute number of processed bytes]. 152 */ 153#ifndef CONFIG_64BIT 154#define __crypt_s390_set_result \ 155 " lr %0,%[result] \n" 156#else /* CONFIG_64BIT */ 157#define __crypt_s390_set_result \ 158 " lgr %0,%[result] \n" 159#endif 160 161/* 162 * Executes the KM (CIPHER MESSAGE) operation of the CPU. 163 * @param func: the function code passed to KM; see crypt_s390_km_func 164 * @param param: address of parameter block; see POP for details on each func 165 * @param dest: address of destination memory area 166 * @param src: address of source memory area 167 * @param src_len: length of src operand in bytes 168 * @returns < zero for failure, 0 for the query func, number of processed bytes 169 * for encryption/decryption funcs 170 */ 171static inline int 172crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len) 173{ 174 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 175 register void* __param asm("1") = param; 176 register u8* __dest asm("4") = dest; 177 register const u8* __src asm("2") = src; 178 register long __src_len asm("3") = src_len; 179 int ret; 180 181 ret = 0; 182 __asm__ __volatile__ ( 183 "0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */ 184 "1: brc 1,0b \n" /* handle partial completion */ 185 __crypt_s390_set_result 186 "6: \n" 187 __crypt_s390_fixup 188 : "+d" (ret), "+a" (__dest), "+a" (__src), 189 [result] "+d" (__src_len) 190 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 191 "a" (__param) 192 : "cc", "memory" 193 ); 194 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ 195 ret = src_len - ret; 196 } 197 return ret; 198} 199 200/* 201 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. 202 * @param func: the function code passed to KM; see crypt_s390_kmc_func 203 * @param param: address of parameter block; see POP for details on each func 204 * @param dest: address of destination memory area 205 * @param src: address of source memory area 206 * @param src_len: length of src operand in bytes 207 * @returns < zero for failure, 0 for the query func, number of processed bytes 208 * for encryption/decryption funcs 209 */ 210static inline int 211crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len) 212{ 213 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 214 register void* __param asm("1") = param; 215 register u8* __dest asm("4") = dest; 216 register const u8* __src asm("2") = src; 217 register long __src_len asm("3") = src_len; 218 int ret; 219 220 ret = 0; 221 __asm__ __volatile__ ( 222 "0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */ 223 "1: brc 1,0b \n" /* handle partial completion */ 224 __crypt_s390_set_result 225 "6: \n" 226 __crypt_s390_fixup 227 : "+d" (ret), "+a" (__dest), "+a" (__src), 228 [result] "+d" (__src_len) 229 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 230 "a" (__param) 231 : "cc", "memory" 232 ); 233 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ 234 ret = src_len - ret; 235 } 236 return ret; 237} 238 239/* 240 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 241 * of the CPU. 242 * @param func: the function code passed to KM; see crypt_s390_kimd_func 243 * @param param: address of parameter block; see POP for details on each func 244 * @param src: address of source memory area 245 * @param src_len: length of src operand in bytes 246 * @returns < zero for failure, 0 for the query func, number of processed bytes 247 * for digest funcs 248 */ 249static inline int 250crypt_s390_kimd(long func, void* param, const u8* src, long src_len) 251{ 252 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 253 register void* __param asm("1") = param; 254 register const u8* __src asm("2") = src; 255 register long __src_len asm("3") = src_len; 256 int ret; 257 258 ret = 0; 259 __asm__ __volatile__ ( 260 "0: .insn rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */ 261 "1: brc 1,0b \n" /* handle partical completion */ 262 __crypt_s390_set_result 263 "6: \n" 264 __crypt_s390_fixup 265 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 266 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 267 "a" (__param) 268 : "cc", "memory" 269 ); 270 if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){ 271 ret = src_len - ret; 272 } 273 return ret; 274} 275 276/* 277 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. 278 * @param func: the function code passed to KM; see crypt_s390_klmd_func 279 * @param param: address of parameter block; see POP for details on each func 280 * @param src: address of source memory area 281 * @param src_len: length of src operand in bytes 282 * @returns < zero for failure, 0 for the query func, number of processed bytes 283 * for digest funcs 284 */ 285static inline int 286crypt_s390_klmd(long func, void* param, const u8* src, long src_len) 287{ 288 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 289 register void* __param asm("1") = param; 290 register const u8* __src asm("2") = src; 291 register long __src_len asm("3") = src_len; 292 int ret; 293 294 ret = 0; 295 __asm__ __volatile__ ( 296 "0: .insn rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */ 297 "1: brc 1,0b \n" /* handle partical completion */ 298 __crypt_s390_set_result 299 "6: \n" 300 __crypt_s390_fixup 301 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 302 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 303 "a" (__param) 304 : "cc", "memory" 305 ); 306 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ 307 ret = src_len - ret; 308 } 309 return ret; 310} 311 312/* 313 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 314 * of the CPU. 315 * @param func: the function code passed to KM; see crypt_s390_klmd_func 316 * @param param: address of parameter block; see POP for details on each func 317 * @param src: address of source memory area 318 * @param src_len: length of src operand in bytes 319 * @returns < zero for failure, 0 for the query func, number of processed bytes 320 * for digest funcs 321 */ 322static inline int 323crypt_s390_kmac(long func, void* param, const u8* src, long src_len) 324{ 325 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 326 register void* __param asm("1") = param; 327 register const u8* __src asm("2") = src; 328 register long __src_len asm("3") = src_len; 329 int ret; 330 331 ret = 0; 332 __asm__ __volatile__ ( 333 "0: .insn rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */ 334 "1: brc 1,0b \n" /* handle partical completion */ 335 __crypt_s390_set_result 336 "6: \n" 337 __crypt_s390_fixup 338 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 339 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 340 "a" (__param) 341 : "cc", "memory" 342 ); 343 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ 344 ret = src_len - ret; 345 } 346 return ret; 347} 348 349/** 350 * Tests if a specific crypto function is implemented on the machine. 351 * @param func: the function code of the specific function; 0 if op in general 352 * @return 1 if func available; 0 if func or op in general not available 353 */ 354static inline int 355crypt_s390_func_available(int func) 356{ 357 int ret; 358 359 struct crypt_s390_query_status status = { 360 .high = 0, 361 .low = 0 362 }; 363 switch (func & CRYPT_S390_OP_MASK){ 364 case CRYPT_S390_KM: 365 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); 366 break; 367 case CRYPT_S390_KMC: 368 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); 369 break; 370 case CRYPT_S390_KIMD: 371 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); 372 break; 373 case CRYPT_S390_KLMD: 374 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); 375 break; 376 case CRYPT_S390_KMAC: 377 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); 378 break; 379 default: 380 ret = 0; 381 return ret; 382 } 383 if (ret >= 0){ 384 func &= CRYPT_S390_FUNC_MASK; 385 func &= 0x7f; //mask modifier bit 386 if (func < 64){ 387 ret = (status.high >> (64 - func - 1)) & 0x1; 388 } else { 389 ret = (status.low >> (128 - func - 1)) & 0x1; 390 } 391 } else { 392 ret = 0; 393 } 394 return ret; 395} 396 397#endif // _CRYPTO_ARCH_S390_CRYPT_S390_H