/* crypto/modes/wrap128.c */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project. Mode with padding contributed by Petr Spacek
 * (pspacek@redhat.com).
 */
/* ====================================================================
 * Copyright (c) 2013 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

/**  Beware!
 *
 *  Following wrapping modes were designed for AES but this implementation
 *  allows you to use them for any 128 bit block cipher.
 */

#include "cryptlib.h"
#include <openssl/modes.h>

/** RFC 3394 section 2.2.3.1 Default Initial Value */
static const unsigned char default_iv[] = {
    0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
};

/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */
static const unsigned char default_aiv[] = {
    0xA6, 0x59, 0x59, 0xA6
};

/** Input size limit: lower than maximum of standards but far larger than
 *  anything that will be used in practice.
 */
#define CRYPTO128_WRAP_MAX (1UL << 31)

/** Wrapping according to RFC 3394 section 2.2.1.
 *
 *  @param[in]  key    Key value.
 *  @param[in]  iv     IV value. Length = 8 bytes. NULL = use default_iv.
 *  @param[in]  in     Plain text as n 64-bit blocks, n >= 2.
 *  @param[in]  inlen  Length of in.
 *  @param[out] out    Cipher text. Minimal buffer length = (inlen + 8) bytes.
 *                     Input and output buffers can overlap if block function
 *                     supports that.
 *  @param[in]  block  Block processing function.
 *  @return            0 if inlen does not consist of n 64-bit blocks, n >= 2.
 *                     or if inlen > CRYPTO128_WRAP_MAX.
 *                     Output length if wrapping succeeded.
 */
size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
                       unsigned char *out,
                       const unsigned char *in, size_t inlen,
                       block128_f block)
{
    unsigned char *A, B[16], *R;
    size_t i, j, t;
    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
        return 0;
    A = B;
    t = 1;
    memmove(out + 8, in, inlen);
    if (!iv)
        iv = default_iv;

    memcpy(A, iv, 8);

    for (j = 0; j < 6; j++) {
        R = out + 8;
        for (i = 0; i < inlen; i += 8, t++, R += 8) {
            memcpy(B + 8, R, 8);
            block(B, B, key);
            A[7] ^= (unsigned char)(t & 0xff);
            if (t > 0xff) {
                A[6] ^= (unsigned char)((t >> 8) & 0xff);
                A[5] ^= (unsigned char)((t >> 16) & 0xff);
                A[4] ^= (unsigned char)((t >> 24) & 0xff);
            }
            memcpy(R, B + 8, 8);
        }
    }
    memcpy(out, A, 8);
    return inlen + 8;
}

/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2.
 *  IV check (step 3) is responsibility of the caller.
 *
 *  @param[in]  key    Key value.
 *  @param[out] iv     Unchecked IV value. Minimal buffer length = 8 bytes.
 *  @param[out] out    Plain text without IV.
 *                     Minimal buffer length = (inlen - 8) bytes.
 *                     Input and output buffers can overlap if block function
 *                     supports that.
 *  @param[in]  in     Ciphertext text as n 64-bit blocks
 *  @param[in]  inlen  Length of in.
 *  @param[in]  block  Block processing function.
 *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
 *                     or if inlen is not multiply of 8.
 *                     Output length otherwise.
 */
static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv,
                                    unsigned char *out,
                                    const unsigned char *in, size_t inlen,
                                    block128_f block)
{
    unsigned char *A, B[16], *R;
    size_t i, j, t;
    inlen -= 8;
    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
        return 0;
    A = B;
    t = 6 * (inlen >> 3);
    memcpy(A, in, 8);
    memmove(out, in + 8, inlen);
    for (j = 0; j < 6; j++) {
        R = out + inlen - 8;
        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
            A[7] ^= (unsigned char)(t & 0xff);
            if (t > 0xff) {
                A[6] ^= (unsigned char)((t >> 8) & 0xff);
                A[5] ^= (unsigned char)((t >> 16) & 0xff);
                A[4] ^= (unsigned char)((t >> 24) & 0xff);
            }
            memcpy(B + 8, R, 8);
            block(B, B, key);
            memcpy(R, B + 8, 8);
        }
    }
    memcpy(iv, A, 8);
    return inlen;
}

/** Unwrapping according to RFC 3394 section 2.2.2 including IV check.
 *  First block of plain text have to match supplied IV otherwise an error is
 *  returned.
 *
 *  @param[in]  key    Key value.
 *  @param[out] iv     Unchecked IV value. Minimal buffer length = 8 bytes.
 *  @param[out] out    Plain text without IV.
 *                     Minimal buffer length = (inlen - 8) bytes.
 *                     Input and output buffers can overlap if block function
 *                     supports that.
 *  @param[in]  in     Ciphertext text as n 64-bit blocks
 *  @param[in]  inlen  Length of in.
 *  @param[in]  block  Block processing function.
 *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
 *                     or if inlen is not multiply of 8
 *                     or if IV doesn't match expected value.
 *                     Output length otherwise.
 */
size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
                         unsigned char *out, const unsigned char *in,
                         size_t inlen, block128_f block)
{
    size_t ret;
    unsigned char got_iv[8];

    ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block);
    if (ret != inlen)
        return ret;

    if (!iv)
        iv = default_iv;
    if (CRYPTO_memcmp(out, iv, 8)) {
        OPENSSL_cleanse(out, inlen);
        return 0;
    }
    return inlen;
}

/** Wrapping according to RFC 5649 section 4.1.
 *
 *  @param[in]  key    Key value.
 *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
 *  @param[out] out    Cipher text. Minimal buffer length = (inlen + 15) bytes.
 *                     Input and output buffers can overlap if block function
 *                     supports that.
 *  @param[in]  in     Plain text as n 64-bit blocks, n >= 2.
 *  @param[in]  inlen  Length of in.
 *  @param[in]  block  Block processing function.
 *  @return            0 if inlen is out of range [1, CRYPTO128_WRAP_MAX].
 *                     Output length if wrapping succeeded.
 */
size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
                           unsigned char *out,
                           const unsigned char *in, size_t inlen,
                           block128_f block)
{
    /* n: number of 64-bit blocks in the padded key data */
    const size_t blocks_padded = (inlen + 8) / 8;
    const size_t padded_len = blocks_padded * 8;
    const size_t padding_len = padded_len - inlen;
    /* RFC 5649 section 3: Alternative Initial Value */
    unsigned char aiv[8];
    int ret;

    /* Section 1: use 32-bit fixed field for plaintext octet length */
    if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX)
        return 0;

    /* Section 3: Alternative Initial Value */
    if (!icv)
        memcpy(aiv, default_aiv, 4);
    else
        memcpy(aiv, icv, 4);    /* Standard doesn't mention this. */

    aiv[4] = (inlen >> 24) & 0xFF;
    aiv[5] = (inlen >> 16) & 0xFF;
    aiv[6] = (inlen >> 8) & 0xFF;
    aiv[7] = inlen & 0xFF;

    if (padded_len == 8) {
        /*
         * Section 4.1 - special case in step 2: If the padded plaintext
         * contains exactly eight octets, then prepend the AIV and encrypt
         * the resulting 128-bit block using AES in ECB mode.
         */
        memmove(out + 8, in, inlen);
        memcpy(out, aiv, 8);
        memset(out + 8 + inlen, 0, padding_len);
        block(out, out, key);
        ret = 16;               /* AIV + padded input */
    } else {
        memmove(out, in, inlen);
        memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */
        ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block);
    }

    return ret;
}

/** Unwrapping according to RFC 5649 section 4.2.
 *
 *  @param[in]  key    Key value.
 *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
 *  @param[out] out    Plain text. Minimal buffer length = inlen bytes.
 *                     Input and output buffers can overlap if block function
 *                     supports that.
 *  @param[in]  in     Ciphertext text as n 64-bit blocks
 *  @param[in]  inlen  Length of in.
 *  @param[in]  block  Block processing function.
 *  @return            0 if inlen is out of range [16, CRYPTO128_WRAP_MAX],
 *                     or if inlen is not multiply of 8
 *                     or if IV and message length indicator doesn't match.
 *                     Output length if unwrapping succeeded and IV matches.
 */
size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
                             unsigned char *out,
                             const unsigned char *in, size_t inlen,
                             block128_f block)
{
    /* n: number of 64-bit blocks in the padded key data */
    size_t n = inlen / 8 - 1;
    size_t padded_len;
    size_t padding_len;
    size_t ptext_len;
    /* RFC 5649 section 3: Alternative Initial Value */
    unsigned char aiv[8];
    static unsigned char zeros[8] = { 0x0 };
    size_t ret;

    /* Section 4.2: Cipher text length has to be (n+1) 64-bit blocks. */
    if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX)
        return 0;

    memmove(out, in, inlen);
    if (inlen == 16) {
        /*
         * Section 4.2 - special case in step 1: When n=1, the ciphertext
         * contains exactly two 64-bit blocks and they are decrypted as a
         * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] |
         * C[1])
         */
        block(out, out, key);
        memcpy(aiv, out, 8);
        /* Remove AIV */
        memmove(out, out + 8, 8);
        padded_len = 8;
    } else {
        padded_len = inlen - 8;
        ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block);
        if (padded_len != ret) {
            OPENSSL_cleanse(out, inlen);
            return 0;
        }
    }

    /*
     * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a
     * user-supplied value can be used (even if standard doesn't mention
     * this).
     */
    if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4))
        || (icv && CRYPTO_memcmp(aiv, icv, 4))) {
        OPENSSL_cleanse(out, inlen);
        return 0;
    }

    /*
     * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len =
     * LSB(32,AIV).
     */

    ptext_len = (aiv[4] << 24) | (aiv[5] << 16) | (aiv[6] << 8) | aiv[7];
    if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) {
        OPENSSL_cleanse(out, inlen);
        return 0;
    }

    /*
     * Check that the rightmost padding_len octets of the output data are
     * zero.
     */
    padding_len = padded_len - ptext_len;
    if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) {
        OPENSSL_cleanse(out, inlen);
        return 0;
    }

    /* Section 4.2 step 3: Remove padding */
    return ptext_len;
}
