-/* 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/)"
+ * Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * 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.
- * ====================================================================
+ * Licensed under the OpenSSL license (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
*/
/** Beware!
* allows you to use them for any 128 bit block cipher.
*/
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/modes.h>
/** RFC 3394 section 2.2.3.1 Default Initial Value */
*
* @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] in Plaintext as n 64-bit blocks, n >= 2.
* @param[in] inlen Length of in.
- * @param[out] out Cipher text. Minimal buffer length = (inlen + 8) bytes.
+ * @param[out] out Ciphertext. Minimal buffer length = (inlen + 8) bytes.
* Input and output buffers can overlap if block function
* supports that.
* @param[in] block Block processing function.
}
/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2.
- * IV check (step 3) is responsibility of the caller.
+ * The 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.
+ * @param[out] out Plaintext 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] in Ciphertext 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 inlen is not a multiple of 8.
* Output length otherwise.
*/
static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv,
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.
+/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check.
+ * The first block of plaintext has to match the 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.
+ * @param[out] iv IV value to match against. Length = 8 bytes.
+ * NULL = use default_iv.
+ * @param[out] out Plaintext 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] in Ciphertext 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 inlen is not a multiple of 8
* or if IV doesn't match expected value.
* Output length otherwise.
*/
unsigned char got_iv[8];
ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block);
- if (ret != inlen)
- return ret;
+ if (ret == 0)
+ return 0;
if (!iv)
iv = default_iv;
- if (CRYPTO_memcmp(out, iv, 8)) {
- OPENSSL_cleanse(out, inlen);
+ if (CRYPTO_memcmp(got_iv, iv, 8)) {
+ OPENSSL_cleanse(out, ret);
return 0;
}
- return inlen;
+ return ret;
}
/** 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.
+ * @param[out] out Ciphertext. 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] in Plaintext 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].
*
* @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.
+ * @param[out] out Plaintext. 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] in Ciphertext 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 inlen is not a multiple of 8
* or if IV and message length indicator doesn't match.
* Output length if unwrapping succeeded and IV matches.
*/
static unsigned char zeros[8] = { 0x0 };
size_t ret;
- /* Section 4.2: Cipher text length has to be (n+1) 64-bit blocks. */
+ /* Section 4.2: Ciphertext 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
* 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);
+ unsigned char buff[16];
+
+ block(in, buff, key);
+ memcpy(aiv, buff, 8);
/* Remove AIV */
- memmove(out, out + 8, 8);
+ memcpy(out, buff + 8, 8);
padded_len = 8;
+ OPENSSL_cleanse(buff, inlen);
} else {
padded_len = inlen - 8;
- ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block);
+ ret = crypto_128_unwrap_raw(key, aiv, out, in, inlen, block);
if (padded_len != ret) {
OPENSSL_cleanse(out, inlen);
return 0;
* LSB(32,AIV).
*/
- ptext_len = (aiv[4] << 24) | (aiv[5] << 16) | (aiv[6] << 8) | aiv[7];
+ ptext_len = ((unsigned int)aiv[4] << 24)
+ | ((unsigned int)aiv[5] << 16)
+ | ((unsigned int)aiv[6] << 8)
+ | (unsigned int)aiv[7];
if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) {
OPENSSL_cleanse(out, inlen);
return 0;