123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- /*
- * IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr.
- * This file is included by cipher_aes_hw.c
- */
- #include "s390x_arch.h"
- #include <stdio.h>
- #define s390x_aes_cbc_initkey cipher_hw_aes_initkey
- #define s390x_aes_cfb1_initkey cipher_hw_aes_initkey
- #define s390x_aes_ctr_initkey cipher_hw_aes_initkey
- #define s390x_aes_cbc_cipher_hw ossl_cipher_hw_generic_cbc
- #define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1
- #define s390x_aes_ctr_cipher_hw ossl_cipher_hw_generic_ctr
- #define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE
- #define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE
- #define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE
- #define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE
- #define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE
- #define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE
- static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat,
- const unsigned char *key, size_t keylen)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- adat->plat.s390x.fc = S390X_AES_FC(keylen);
- memcpy(adat->plat.s390x.param.km.k, key, keylen);
- return 1;
- }
- static int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;
- s390x_km(in, len, out, adat->plat.s390x.fc | modifier,
- &adat->plat.s390x.param.km);
- return 1;
- }
- static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat,
- const unsigned char *key, size_t keylen)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
- adat->plat.s390x.fc = S390X_AES_FC(keylen);
- adat->plat.s390x.res = 0;
- return 1;
- }
- static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- int n = adat->plat.s390x.res;
- int rem;
- memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
- while (n && len) {
- *out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n];
- n = (n + 1) & 0xf;
- --len;
- ++in;
- ++out;
- }
- rem = len & 0xf;
- len &= ~(size_t)0xf;
- if (len) {
- s390x_kmo(in, len, out, adat->plat.s390x.fc,
- &adat->plat.s390x.param.kmo_kmf);
- out += len;
- in += len;
- }
- if (rem) {
- s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
- adat->plat.s390x.param.kmo_kmf.cv,
- adat->plat.s390x.fc,
- adat->plat.s390x.param.kmo_kmf.k);
- while (rem--) {
- out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n];
- ++n;
- }
- }
- memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
- adat->plat.s390x.res = n;
- return 1;
- }
- static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat,
- const unsigned char *key, size_t keylen)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- adat->plat.s390x.fc = S390X_AES_FC(keylen);
- adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */
- adat->plat.s390x.res = 0;
- memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
- return 1;
- }
- static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;
- int n = adat->plat.s390x.res;
- int rem;
- unsigned char tmp;
- memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
- while (n && len) {
- tmp = *in;
- *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
- adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
- n = (n + 1) & 0xf;
- --len;
- ++in;
- ++out;
- }
- rem = len & 0xf;
- len &= ~(size_t)0xf;
- if (len) {
- s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier,
- &adat->plat.s390x.param.kmo_kmf);
- out += len;
- in += len;
- }
- if (rem) {
- s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
- adat->plat.s390x.param.kmo_kmf.cv,
- S390X_AES_FC(dat->keylen),
- adat->plat.s390x.param.kmo_kmf.k);
- while (rem--) {
- tmp = in[n];
- out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
- adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
- ++n;
- }
- }
- memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
- adat->plat.s390x.res = n;
- return 1;
- }
- static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat,
- const unsigned char *key, size_t keylen)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- adat->plat.s390x.fc = S390X_AES_FC(keylen);
- adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */
- memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
- return 1;
- }
- static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
- unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;
- memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
- s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier,
- &adat->plat.s390x.param.kmo_kmf);
- memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
- return 1;
- }
- #define PROV_CIPHER_HW_declare(mode) \
- static const PROV_CIPHER_HW s390x_aes_##mode = { \
- s390x_aes_##mode##_initkey, \
- s390x_aes_##mode##_cipher_hw, \
- cipher_hw_aes_copyctx \
- };
- #define PROV_CIPHER_HW_select(mode) \
- if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \
- || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \
- || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \
- return &s390x_aes_##mode;
|