mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Instead of using AF_ALG to calculate key verification patterns, transform the key blob into a protected key and calculate the key verification patterns with CAPCF calls. The 'zkey-cryptsetup convert' command also calculates key verification patterns from clear keys. Support this, too. Reviewed-by: Finn Callies <fcallies@linux.ibm.com> Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
325 lines
7.3 KiB
C
325 lines
7.3 KiB
C
/*
|
|
* zkey - Generate, re-encipher, and validate secure keys
|
|
*
|
|
* This header file defines the interface to the pkey kernel module.
|
|
* It defines a set of IOCTL commands with its associated structures.
|
|
*
|
|
* Copyright IBM Corp. 2017, 2024
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#ifndef CPACF_H
|
|
#define CPACF_H
|
|
|
|
#include "lib/zt_common.h"
|
|
|
|
int cpacf_aes_cbc_enc(const u8 *key, size_t key_size,
|
|
const u8 *in, u8 *out, size_t size,
|
|
int pkey_type);
|
|
int cpacf_aes_xts_enc(const u8 *key, size_t key_size,
|
|
const u8 *in, u8 *out, size_t size,
|
|
int pkey_type);
|
|
int cpacf_aes_xts_full_enc(const u8 *key, size_t key_size,
|
|
const u8 *in, u8 *out, size_t size,
|
|
int pkey_type);
|
|
int cpacf_hmac_sha(const u8 *key, size_t key_size,
|
|
const u8 *in, size_t in_size,
|
|
u8 *mac, size_t mac_size,
|
|
int pkey_type);
|
|
|
|
#define MSA 17 /* message-security-assist */
|
|
#define MSA4 77 /* message-security-assist extension 4 */
|
|
|
|
/* STFLE (store facility list extended) */
|
|
|
|
static inline unsigned long stfle(u64 flist[], u8 nmemb)
|
|
{
|
|
register unsigned long r0 __asm__("0") = (unsigned long)nmemb - 1;
|
|
|
|
__asm__ volatile(
|
|
".insn s,%[opc]<<16,0(%[flist])"
|
|
: "+d" (r0)
|
|
: [flist] "a" (flist), [opc] "i" (0xb2b0)
|
|
: "memory", "cc"
|
|
);
|
|
|
|
return r0 + 1;
|
|
}
|
|
|
|
/* KM */
|
|
|
|
/* Function codes */
|
|
#define CPACF_KM_QUERY 0
|
|
#define CPACF_KM_XTS_AES_128 50
|
|
#define CPACF_KM_XTS_AES_256 52
|
|
#define CPACF_KM_XTS_ENCRYPTED_AES_128 58
|
|
#define CPACF_KM_XTS_ENCRYPTED_AES_256 60
|
|
#define CPACF_KM_FXTS_ENCRYPTED_AES_128 90
|
|
#define CPACF_KM_FXTS_ENCRYPTED_AES_256 92
|
|
|
|
struct cpacf_km_xts_aes_128_param {
|
|
u8 key[16];
|
|
u8 xtsparam[16];
|
|
};
|
|
|
|
struct cpacf_km_xts_aes_256_param {
|
|
u8 key[32];
|
|
u8 xtsparam[16];
|
|
};
|
|
|
|
struct cpacf_km_enc_xts_aes_128_param {
|
|
u8 protkey[48]; /* WKa(K)|WKaVP */
|
|
u8 xtsparam[16];
|
|
};
|
|
|
|
struct cpacf_km_enc_xts_aes_256_param {
|
|
u8 protkey[64]; /* WKa(K)|WKaVP */
|
|
u8 xtsparam[16];
|
|
};
|
|
|
|
struct cpacf_km_xts_full_aes_128_param {
|
|
u8 protkey[32]; /* WKa(K) */
|
|
u8 tweak[16];
|
|
u8 nap[16];
|
|
u8 wkvp[32]; /* WKaVP */
|
|
};
|
|
|
|
struct cpacf_km_xts_full_aes_256_param {
|
|
u8 protkey[64]; /* WKa(K) */
|
|
u8 tweak[16];
|
|
u8 nap[16];
|
|
u8 wkvp[32]; /* WKaVP */
|
|
};
|
|
|
|
static inline int cpacf_km(unsigned long fc, void *param, u8 *out,
|
|
const u8 *in, unsigned long inlen,
|
|
unsigned long *bytes_processed)
|
|
{
|
|
register unsigned long r0 __asm__("0") = (unsigned long)fc;
|
|
register unsigned long r1 __asm__("1") = (unsigned long)param;
|
|
register unsigned long r2 __asm__("2") = (unsigned long)in;
|
|
register unsigned long r3 __asm__("3") = (unsigned long)inlen;
|
|
register unsigned long r4 __asm__("4") = (unsigned long)out;
|
|
u8 cc;
|
|
|
|
__asm__ volatile(
|
|
"0: .insn rre,%[opc] << 16,%[out],%[in]\n"
|
|
" brc 1,0b\n" /* handle partial completion */
|
|
" ipm %[cc]\n"
|
|
" srl %[cc],28\n"
|
|
: [in] "+a" (r2), [inlen] "+d" (r3), [out] "+a" (r4),
|
|
[cc] "=d" (cc)
|
|
: [fc] "d" (r0), [param] "a" (r1), [opc] "i" (0xb92e)
|
|
: "cc", "memory"
|
|
);
|
|
|
|
if (bytes_processed != NULL)
|
|
*bytes_processed = fc ? inlen - r3 : r3;
|
|
|
|
return cc;
|
|
}
|
|
|
|
/* KMC */
|
|
|
|
/* Function codes */
|
|
#define CPACF_KMC_QUERY 0
|
|
#define CPACF_KMC_AES_128 18
|
|
#define CPACF_KMC_AES_192 19
|
|
#define CPACF_KMC_AES_256 20
|
|
#define CPACF_KMC_ENCRYPTED_AES_128 26
|
|
#define CPACF_KMC_ENCRYPTED_AES_192 27
|
|
#define CPACF_KMC_ENCRYPTED_AES_256 28
|
|
|
|
struct cpacf_kmc_aes_128_param {
|
|
u8 cv[16];
|
|
u8 key[16];
|
|
};
|
|
|
|
struct cpacf_kmc_aes_192_param {
|
|
u8 cv[16];
|
|
u8 key[24];
|
|
};
|
|
|
|
struct cpacf_kmc_aes_256_param {
|
|
u8 cv[16];
|
|
u8 key[32];
|
|
};
|
|
|
|
struct cpacf_kmc_enc_aes_128_param {
|
|
u8 cv[16];
|
|
u8 protkey[48]; /* WKa(K)|WKaVP */
|
|
};
|
|
|
|
struct cpacf_kmc_enc_aes_192_param {
|
|
u8 cv[16];
|
|
u8 protkey[56]; /* WKa(K)|WKaVP */
|
|
};
|
|
|
|
struct cpacf_kmc_enc_aes_256_param {
|
|
u8 cv[16];
|
|
u8 protkey[64]; /* WKa(K)|WKaVP */
|
|
};
|
|
|
|
static inline int cpacf_kmc(unsigned long fc, void *param, u8 *out,
|
|
const u8 *in, long inlen,
|
|
unsigned long *bytes_processed)
|
|
{
|
|
register unsigned long r0 __asm__("0") = (unsigned long)fc;
|
|
register unsigned long r1 __asm__("1") = (unsigned long)param;
|
|
register unsigned long r2 __asm__("2") = (unsigned long)in;
|
|
register unsigned long r3 __asm__("3") = (unsigned long)inlen;
|
|
register unsigned long r4 __asm__("4") = (unsigned long)out;
|
|
u8 cc;
|
|
|
|
__asm__ volatile(
|
|
"0: .insn rre,%[opc] << 16,%[out],%[in]\n"
|
|
" brc 1,0b\n" /* handle partial completion */
|
|
" ipm %[cc]\n"
|
|
" srl %[cc],28\n"
|
|
: [in] "+a" (r2), [inlen] "+d" (r3), [out] "+a" (r4),
|
|
[cc] "=d" (cc)
|
|
: [fc] "d" (r0), [param] "a" (r1), [opc] "i" (0xb92f)
|
|
: "cc", "memory"
|
|
);
|
|
|
|
if (bytes_processed != NULL)
|
|
*bytes_processed = fc ? inlen - r3 : r3;
|
|
|
|
return cc;
|
|
}
|
|
|
|
/* KMAC */
|
|
|
|
/* Function codes */
|
|
#define CPACF_KMAC_QUERY 0
|
|
#define CPACF_KMAC_HMAC_SHA_256 113
|
|
#define CPACF_KMAC_HMAC_SHA_512 115
|
|
#define CPACF_KMAC_HMAC_ENCRYPTED_SHA_256 121
|
|
#define CPACF_KMAC_HMAC_ENCRYPTED_SHA_512 123
|
|
|
|
/* Flags */
|
|
#define CPACF_KMAC_IKP 0x8000
|
|
#define CPACF_KMAC_IIMP 0x4000
|
|
#define CPACF_KMAC_CCUP 0x2000
|
|
|
|
struct cpacf_kmac_hmac_224_256_param {
|
|
u32 h[8];
|
|
u64 imbl;
|
|
unsigned char key[64];
|
|
};
|
|
|
|
struct cpacf_kmac_hmac_384_512_param {
|
|
u64 h[8];
|
|
#ifdef __SIZEOF_INT128__
|
|
u128 imbl;
|
|
#else
|
|
u64 imblhi;
|
|
u64 imbl;
|
|
#endif
|
|
unsigned char key[128];
|
|
};
|
|
|
|
struct cpacf_kmac_enc_hmac_224_256_param {
|
|
u32 h[8];
|
|
u64 imbl;
|
|
unsigned char protkey[96]; /* WKa(K)|WKaVP */
|
|
};
|
|
|
|
struct cpacf_kmac_enc_hmac_384_512_param {
|
|
u64 h[8];
|
|
#ifdef __SIZEOF_INT128__
|
|
u128 imbl;
|
|
#else
|
|
u64 imblhi;
|
|
u64 imbl;
|
|
#endif
|
|
unsigned char protkey[160]; /* WKa(K)|WKaVP */
|
|
};
|
|
|
|
static inline int cpacf_kmac(unsigned long fc, void *param, const u8 *in,
|
|
unsigned long inlen)
|
|
{
|
|
register unsigned long r0 __asm__("0") = (unsigned long)fc;
|
|
register unsigned long r1 __asm__("1") = (unsigned long)param;
|
|
register unsigned long r2 __asm__("2") = (unsigned long)in;
|
|
register unsigned long r3 __asm__("3") = (unsigned long)inlen;
|
|
u8 cc;
|
|
|
|
__asm__ volatile(
|
|
"0: .insn rre,%[opc] << 16,0,%[in]\n"
|
|
" brc 1,0b\n" /* handle partial completion */
|
|
" ipm %[cc]\n"
|
|
" srl %[cc],28\n"
|
|
: [in] "+a" (r2), [inlen] "+d" (r3), [cc] "=d" (cc)
|
|
: [fc] "d" (r0), [param] "a" (r1), [opc] "i" (0xb91e)
|
|
: "cc", "memory"
|
|
);
|
|
|
|
return cc;
|
|
}
|
|
|
|
/* PCC */
|
|
|
|
/* Function codes */
|
|
#define CPACF_PCC_QUERY 0
|
|
#define CPACF_PCC_XTS_AES_128 50
|
|
#define CPACF_PCC_XTS_AES_256 52
|
|
#define CPACF_PCC_XTS_ENCRYPTED_AES_128 58
|
|
#define CPACF_PCC_XTS_ENCRYPTED_AES_256 60
|
|
|
|
struct cpacf_pcc_xts_aes_128_param {
|
|
u8 key[16];
|
|
u8 i[16];
|
|
u8 j[16];
|
|
u8 t[16];
|
|
u8 xtsparams[16];
|
|
};
|
|
|
|
struct cpacf_pcc_xts_aes_256_param {
|
|
u8 key[32];
|
|
u8 i[16];
|
|
u8 j[16];
|
|
u8 t[16];
|
|
u8 xtsparams[16];
|
|
};
|
|
|
|
struct cpacf_pcc_enc_xts_aes_128_param {
|
|
u8 protkey[48]; /* WKa(K)|WKaVP */
|
|
u8 i[16];
|
|
u8 j[16];
|
|
u8 t[16];
|
|
u8 xtsparams[16];
|
|
};
|
|
|
|
struct cpacf_pcc_enc_xts_aes_256_param {
|
|
u8 protkey[64]; /* WKa(K)|WKaVP */
|
|
u8 i[16];
|
|
u8 j[16];
|
|
u8 t[16];
|
|
u8 xtsparams[16];
|
|
};
|
|
|
|
/* PCC (perform cryptographic computation) */
|
|
static inline int cpacf_pcc(unsigned long fc, void *param)
|
|
{
|
|
register unsigned long r0 __asm__("0") = (unsigned long)fc;
|
|
register unsigned long r1 __asm__("1") = (unsigned long)param;
|
|
u8 cc;
|
|
|
|
__asm__ volatile(
|
|
"0: .insn rre,%[opc] << 16,0,0\n" /* PCC opcode */
|
|
" brc 1,0b\n" /* handle partial completion */
|
|
" ipm %[cc]\n"
|
|
" srl %[cc],28\n"
|
|
: [cc] "=d" (cc)
|
|
: [fc] "d" (r0), [param] "a" (r1), [opc] "i" (0xb92c)
|
|
: "cc", "memory"
|
|
);
|
|
|
|
return cc;
|
|
}
|
|
|
|
#endif
|