Files
s390-tools/zkey/cpacf.h
Ingo Franzki 7fffdcfe8c zkey: Remove the use of AF_ALG for calculating key verification patterns
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>
2026-06-22 16:43:03 +02:00

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