1/* crypto/modes/wrap128.c */ 2/* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2013 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 */ 54 55#include "cryptlib.h" 56#include <openssl/modes.h> 57 58static const unsigned char default_iv[] = { 59 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 60}; 61 62/* 63 * Input size limit: lower than maximum of standards but far larger than 64 * anything that will be used in practice. 65 */ 66#define CRYPTO128_WRAP_MAX (1UL << 31) 67 68size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, 69 unsigned char *out, 70 const unsigned char *in, size_t inlen, 71 block128_f block) 72{ 73 unsigned char *A, B[16], *R; 74 size_t i, j, t; 75 if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX)) 76 return 0; 77 A = B; 78 t = 1; 79 memmove(out + 8, in, inlen); 80 if (!iv) 81 iv = default_iv; 82 83 memcpy(A, iv, 8); 84 85 for (j = 0; j < 6; j++) { 86 R = out + 8; 87 for (i = 0; i < inlen; i += 8, t++, R += 8) { 88 memcpy(B + 8, R, 8); 89 block(B, B, key); 90 A[7] ^= (unsigned char)(t & 0xff); 91 if (t > 0xff) { 92 A[6] ^= (unsigned char)((t >> 8) & 0xff); 93 A[5] ^= (unsigned char)((t >> 16) & 0xff); 94 A[4] ^= (unsigned char)((t >> 24) & 0xff); 95 } 96 memcpy(R, B + 8, 8); 97 } 98 } 99 memcpy(out, A, 8); 100 return inlen + 8; 101} 102 103size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, 104 unsigned char *out, 105 const unsigned char *in, size_t inlen, 106 block128_f block) 107{ 108 unsigned char *A, B[16], *R; 109 size_t i, j, t; 110 inlen -= 8; 111 if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) 112 return 0; 113 A = B; 114 t = 6 * (inlen >> 3); 115 memcpy(A, in, 8); 116 memmove(out, in + 8, inlen); 117 for (j = 0; j < 6; j++) { 118 R = out + inlen - 8; 119 for (i = 0; i < inlen; i += 8, t--, R -= 8) { 120 A[7] ^= (unsigned char)(t & 0xff); 121 if (t > 0xff) { 122 A[6] ^= (unsigned char)((t >> 8) & 0xff); 123 A[5] ^= (unsigned char)((t >> 16) & 0xff); 124 A[4] ^= (unsigned char)((t >> 24) & 0xff); 125 } 126 memcpy(B + 8, R, 8); 127 block(B, B, key); 128 memcpy(R, B + 8, 8); 129 } 130 } 131 if (!iv) 132 iv = default_iv; 133 if (memcmp(A, iv, 8)) { 134 OPENSSL_cleanse(out, inlen); 135 return 0; 136 } 137 return inlen; 138} 139