Skip to main content
  • Home
  • login
  • Browse the archive

    swh mirror partner logo
swh logo
SoftwareHeritage
Software
Heritage
Mirror
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • c78f6b3
  • /
  • providers
  • /
  • implementations
  • /
  • ciphers
  • /
  • cipher_aes_hw_s390x.inc
Raw File
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge Iframe embedding
swh:1:cnt:c8282dbd08a9cdd0d18495c2c7ed3df295490768
directory badge Iframe embedding
swh:1:dir:251d45dbdba09f179d5e86dfef9553e2c6a24ec4
cipher_aes_hw_s390x.inc
/*
 * 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;

ENEA — Copyright (C), ENEA. License: GNU AGPLv3+.
Legal notes  ::  JavaScript license information ::  Web API

back to top