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