Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/modes/wrap128.c
Line
Count
Source (jump to first uncovered line)
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
58
static 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
0
#define CRYPTO128_WRAP_MAX (1UL << 31)
67
68
size_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
0
{
73
0
    unsigned char *A, B[16], *R;
74
0
    size_t i, j, t;
75
0
    if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX))
76
0
        return 0;
77
0
    A = B;
78
0
    t = 1;
79
0
    memmove(out + 8, in, inlen);
80
0
    if (!iv)
81
0
        iv = default_iv;
82
83
0
    memcpy(A, iv, 8);
84
85
0
    for (j = 0; j < 6; j++) {
86
0
        R = out + 8;
87
0
        for (i = 0; i < inlen; i += 8, t++, R += 8) {
88
0
            memcpy(B + 8, R, 8);
89
0
            block(B, B, key);
90
0
            A[7] ^= (unsigned char)(t & 0xff);
91
0
            if (t > 0xff) {
92
0
                A[6] ^= (unsigned char)((t >> 8) & 0xff);
93
0
                A[5] ^= (unsigned char)((t >> 16) & 0xff);
94
0
                A[4] ^= (unsigned char)((t >> 24) & 0xff);
95
0
            }
96
0
            memcpy(R, B + 8, 8);
97
0
        }
98
0
    }
99
0
    memcpy(out, A, 8);
100
0
    return inlen + 8;
101
0
}
102
103
size_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
0
{
108
0
    unsigned char *A, B[16], *R;
109
0
    size_t i, j, t;
110
0
    inlen -= 8;
111
0
    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
112
0
        return 0;
113
0
    A = B;
114
0
    t = 6 * (inlen >> 3);
115
0
    memcpy(A, in, 8);
116
0
    memmove(out, in + 8, inlen);
117
0
    for (j = 0; j < 6; j++) {
118
0
        R = out + inlen - 8;
119
0
        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
120
0
            A[7] ^= (unsigned char)(t & 0xff);
121
0
            if (t > 0xff) {
122
0
                A[6] ^= (unsigned char)((t >> 8) & 0xff);
123
0
                A[5] ^= (unsigned char)((t >> 16) & 0xff);
124
0
                A[4] ^= (unsigned char)((t >> 24) & 0xff);
125
0
            }
126
0
            memcpy(B + 8, R, 8);
127
0
            block(B, B, key);
128
0
            memcpy(R, B + 8, 8);
129
0
        }
130
0
    }
131
0
    if (!iv)
132
0
        iv = default_iv;
133
0
    if (memcmp(A, iv, 8)) {
134
0
        OPENSSL_cleanse(out, inlen);
135
0
        return 0;
136
0
    }
137
0
    return inlen;
138
0
}