1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr. 12e1051a39Sopenharmony_ci * This file is included by cipher_aes_hw.c 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci#include "s390x_arch.h" 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <stdio.h> 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#define s390x_aes_cbc_initkey cipher_hw_aes_initkey 20e1051a39Sopenharmony_ci#define s390x_aes_cfb1_initkey cipher_hw_aes_initkey 21e1051a39Sopenharmony_ci#define s390x_aes_ctr_initkey cipher_hw_aes_initkey 22e1051a39Sopenharmony_ci#define s390x_aes_cbc_cipher_hw ossl_cipher_hw_generic_cbc 23e1051a39Sopenharmony_ci#define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1 24e1051a39Sopenharmony_ci#define s390x_aes_ctr_cipher_hw ossl_cipher_hw_generic_ctr 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci#define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE 27e1051a39Sopenharmony_ci#define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE 28e1051a39Sopenharmony_ci#define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE 29e1051a39Sopenharmony_ci#define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE 30e1051a39Sopenharmony_ci#define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE 31e1051a39Sopenharmony_ci#define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_cistatic int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat, 34e1051a39Sopenharmony_ci const unsigned char *key, size_t keylen) 35e1051a39Sopenharmony_ci{ 36e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci adat->plat.s390x.fc = S390X_AES_FC(keylen); 39e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.km.k, key, keylen); 40e1051a39Sopenharmony_ci return 1; 41e1051a39Sopenharmony_ci} 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_cistatic int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, 44e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 45e1051a39Sopenharmony_ci{ 46e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 47e1051a39Sopenharmony_ci unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci s390x_km(in, len, out, adat->plat.s390x.fc | modifier, 50e1051a39Sopenharmony_ci &adat->plat.s390x.param.km); 51e1051a39Sopenharmony_ci return 1; 52e1051a39Sopenharmony_ci} 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_cistatic int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat, 55e1051a39Sopenharmony_ci const unsigned char *key, size_t keylen) 56e1051a39Sopenharmony_ci{ 57e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); 60e1051a39Sopenharmony_ci adat->plat.s390x.fc = S390X_AES_FC(keylen); 61e1051a39Sopenharmony_ci adat->plat.s390x.res = 0; 62e1051a39Sopenharmony_ci return 1; 63e1051a39Sopenharmony_ci} 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_cistatic int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, 66e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 67e1051a39Sopenharmony_ci{ 68e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 69e1051a39Sopenharmony_ci int n = adat->plat.s390x.res; 70e1051a39Sopenharmony_ci int rem; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); 73e1051a39Sopenharmony_ci while (n && len) { 74e1051a39Sopenharmony_ci *out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n]; 75e1051a39Sopenharmony_ci n = (n + 1) & 0xf; 76e1051a39Sopenharmony_ci --len; 77e1051a39Sopenharmony_ci ++in; 78e1051a39Sopenharmony_ci ++out; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci rem = len & 0xf; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci len &= ~(size_t)0xf; 84e1051a39Sopenharmony_ci if (len) { 85e1051a39Sopenharmony_ci s390x_kmo(in, len, out, adat->plat.s390x.fc, 86e1051a39Sopenharmony_ci &adat->plat.s390x.param.kmo_kmf); 87e1051a39Sopenharmony_ci 88e1051a39Sopenharmony_ci out += len; 89e1051a39Sopenharmony_ci in += len; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci if (rem) { 93e1051a39Sopenharmony_ci s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16, 94e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.cv, 95e1051a39Sopenharmony_ci adat->plat.s390x.fc, 96e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.k); 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci while (rem--) { 99e1051a39Sopenharmony_ci out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n]; 100e1051a39Sopenharmony_ci ++n; 101e1051a39Sopenharmony_ci } 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); 105e1051a39Sopenharmony_ci adat->plat.s390x.res = n; 106e1051a39Sopenharmony_ci return 1; 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_cistatic int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat, 110e1051a39Sopenharmony_ci const unsigned char *key, size_t keylen) 111e1051a39Sopenharmony_ci{ 112e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 113e1051a39Sopenharmony_ci 114e1051a39Sopenharmony_ci adat->plat.s390x.fc = S390X_AES_FC(keylen); 115e1051a39Sopenharmony_ci adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */ 116e1051a39Sopenharmony_ci adat->plat.s390x.res = 0; 117e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); 118e1051a39Sopenharmony_ci return 1; 119e1051a39Sopenharmony_ci} 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_cistatic int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, 122e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 125e1051a39Sopenharmony_ci unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; 126e1051a39Sopenharmony_ci int n = adat->plat.s390x.res; 127e1051a39Sopenharmony_ci int rem; 128e1051a39Sopenharmony_ci unsigned char tmp; 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); 131e1051a39Sopenharmony_ci while (n && len) { 132e1051a39Sopenharmony_ci tmp = *in; 133e1051a39Sopenharmony_ci *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; 134e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp; 135e1051a39Sopenharmony_ci n = (n + 1) & 0xf; 136e1051a39Sopenharmony_ci --len; 137e1051a39Sopenharmony_ci ++in; 138e1051a39Sopenharmony_ci ++out; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci rem = len & 0xf; 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ci len &= ~(size_t)0xf; 144e1051a39Sopenharmony_ci if (len) { 145e1051a39Sopenharmony_ci s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, 146e1051a39Sopenharmony_ci &adat->plat.s390x.param.kmo_kmf); 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci out += len; 149e1051a39Sopenharmony_ci in += len; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci if (rem) { 153e1051a39Sopenharmony_ci s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16, 154e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.cv, 155e1051a39Sopenharmony_ci S390X_AES_FC(dat->keylen), 156e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.k); 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci while (rem--) { 159e1051a39Sopenharmony_ci tmp = in[n]; 160e1051a39Sopenharmony_ci out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; 161e1051a39Sopenharmony_ci adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp; 162e1051a39Sopenharmony_ci ++n; 163e1051a39Sopenharmony_ci } 164e1051a39Sopenharmony_ci } 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_ci memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); 167e1051a39Sopenharmony_ci adat->plat.s390x.res = n; 168e1051a39Sopenharmony_ci return 1; 169e1051a39Sopenharmony_ci} 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_cistatic int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat, 172e1051a39Sopenharmony_ci const unsigned char *key, size_t keylen) 173e1051a39Sopenharmony_ci{ 174e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci adat->plat.s390x.fc = S390X_AES_FC(keylen); 177e1051a39Sopenharmony_ci adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */ 178e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); 179e1051a39Sopenharmony_ci return 1; 180e1051a39Sopenharmony_ci} 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_cistatic int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, 183e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 184e1051a39Sopenharmony_ci{ 185e1051a39Sopenharmony_ci PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; 186e1051a39Sopenharmony_ci unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); 189e1051a39Sopenharmony_ci s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, 190e1051a39Sopenharmony_ci &adat->plat.s390x.param.kmo_kmf); 191e1051a39Sopenharmony_ci memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); 192e1051a39Sopenharmony_ci return 1; 193e1051a39Sopenharmony_ci} 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci#define PROV_CIPHER_HW_declare(mode) \ 196e1051a39Sopenharmony_cistatic const PROV_CIPHER_HW s390x_aes_##mode = { \ 197e1051a39Sopenharmony_ci s390x_aes_##mode##_initkey, \ 198e1051a39Sopenharmony_ci s390x_aes_##mode##_cipher_hw, \ 199e1051a39Sopenharmony_ci cipher_hw_aes_copyctx \ 200e1051a39Sopenharmony_ci}; 201e1051a39Sopenharmony_ci#define PROV_CIPHER_HW_select(mode) \ 202e1051a39Sopenharmony_ciif ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \ 203e1051a39Sopenharmony_ci || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \ 204e1051a39Sopenharmony_ci || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \ 205e1051a39Sopenharmony_ci return &s390x_aes_##mode; 206e1051a39Sopenharmony_ci 207