1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/**  Beware!
11e1051a39Sopenharmony_ci *
12e1051a39Sopenharmony_ci *  Following wrapping modes were designed for AES but this implementation
13e1051a39Sopenharmony_ci *  allows you to use them for any 128 bit block cipher.
14e1051a39Sopenharmony_ci */
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
17e1051a39Sopenharmony_ci#include <openssl/modes.h>
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci/** RFC 3394 section 2.2.3.1 Default Initial Value */
20e1051a39Sopenharmony_cistatic const unsigned char default_iv[] = {
21e1051a39Sopenharmony_ci    0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
22e1051a39Sopenharmony_ci};
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */
25e1051a39Sopenharmony_cistatic const unsigned char default_aiv[] = {
26e1051a39Sopenharmony_ci    0xA6, 0x59, 0x59, 0xA6
27e1051a39Sopenharmony_ci};
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci/** Input size limit: lower than maximum of standards but far larger than
30e1051a39Sopenharmony_ci *  anything that will be used in practice.
31e1051a39Sopenharmony_ci */
32e1051a39Sopenharmony_ci#define CRYPTO128_WRAP_MAX (1UL << 31)
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ci/** Wrapping according to RFC 3394 section 2.2.1.
35e1051a39Sopenharmony_ci *
36e1051a39Sopenharmony_ci *  @param[in]  key    Key value.
37e1051a39Sopenharmony_ci *  @param[in]  iv     IV value. Length = 8 bytes. NULL = use default_iv.
38e1051a39Sopenharmony_ci *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
39e1051a39Sopenharmony_ci *  @param[in]  inlen  Length of in.
40e1051a39Sopenharmony_ci *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 8) bytes.
41e1051a39Sopenharmony_ci *                     Input and output buffers can overlap if block function
42e1051a39Sopenharmony_ci *                     supports that.
43e1051a39Sopenharmony_ci *  @param[in]  block  Block processing function.
44e1051a39Sopenharmony_ci *  @return            0 if inlen does not consist of n 64-bit blocks, n >= 2.
45e1051a39Sopenharmony_ci *                     or if inlen > CRYPTO128_WRAP_MAX.
46e1051a39Sopenharmony_ci *                     Output length if wrapping succeeded.
47e1051a39Sopenharmony_ci */
48e1051a39Sopenharmony_cisize_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
49e1051a39Sopenharmony_ci                       unsigned char *out,
50e1051a39Sopenharmony_ci                       const unsigned char *in, size_t inlen,
51e1051a39Sopenharmony_ci                       block128_f block)
52e1051a39Sopenharmony_ci{
53e1051a39Sopenharmony_ci    unsigned char *A, B[16], *R;
54e1051a39Sopenharmony_ci    size_t i, j, t;
55e1051a39Sopenharmony_ci    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
56e1051a39Sopenharmony_ci        return 0;
57e1051a39Sopenharmony_ci    A = B;
58e1051a39Sopenharmony_ci    t = 1;
59e1051a39Sopenharmony_ci    memmove(out + 8, in, inlen);
60e1051a39Sopenharmony_ci    if (!iv)
61e1051a39Sopenharmony_ci        iv = default_iv;
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ci    memcpy(A, iv, 8);
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ci    for (j = 0; j < 6; j++) {
66e1051a39Sopenharmony_ci        R = out + 8;
67e1051a39Sopenharmony_ci        for (i = 0; i < inlen; i += 8, t++, R += 8) {
68e1051a39Sopenharmony_ci            memcpy(B + 8, R, 8);
69e1051a39Sopenharmony_ci            block(B, B, key);
70e1051a39Sopenharmony_ci            A[7] ^= (unsigned char)(t & 0xff);
71e1051a39Sopenharmony_ci            if (t > 0xff) {
72e1051a39Sopenharmony_ci                A[6] ^= (unsigned char)((t >> 8) & 0xff);
73e1051a39Sopenharmony_ci                A[5] ^= (unsigned char)((t >> 16) & 0xff);
74e1051a39Sopenharmony_ci                A[4] ^= (unsigned char)((t >> 24) & 0xff);
75e1051a39Sopenharmony_ci            }
76e1051a39Sopenharmony_ci            memcpy(R, B + 8, 8);
77e1051a39Sopenharmony_ci        }
78e1051a39Sopenharmony_ci    }
79e1051a39Sopenharmony_ci    memcpy(out, A, 8);
80e1051a39Sopenharmony_ci    return inlen + 8;
81e1051a39Sopenharmony_ci}
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_ci/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2.
84e1051a39Sopenharmony_ci *  The IV check (step 3) is responsibility of the caller.
85e1051a39Sopenharmony_ci *
86e1051a39Sopenharmony_ci *  @param[in]  key    Key value.
87e1051a39Sopenharmony_ci *  @param[out] iv     Unchecked IV value. Minimal buffer length = 8 bytes.
88e1051a39Sopenharmony_ci *  @param[out] out    Plaintext without IV.
89e1051a39Sopenharmony_ci *                     Minimal buffer length = (inlen - 8) bytes.
90e1051a39Sopenharmony_ci *                     Input and output buffers can overlap if block function
91e1051a39Sopenharmony_ci *                     supports that.
92e1051a39Sopenharmony_ci *  @param[in]  in     Ciphertext as n 64-bit blocks.
93e1051a39Sopenharmony_ci *  @param[in]  inlen  Length of in.
94e1051a39Sopenharmony_ci *  @param[in]  block  Block processing function.
95e1051a39Sopenharmony_ci *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
96e1051a39Sopenharmony_ci *                     or if inlen is not a multiple of 8.
97e1051a39Sopenharmony_ci *                     Output length otherwise.
98e1051a39Sopenharmony_ci */
99e1051a39Sopenharmony_cistatic size_t crypto_128_unwrap_raw(void *key, unsigned char *iv,
100e1051a39Sopenharmony_ci                                    unsigned char *out,
101e1051a39Sopenharmony_ci                                    const unsigned char *in, size_t inlen,
102e1051a39Sopenharmony_ci                                    block128_f block)
103e1051a39Sopenharmony_ci{
104e1051a39Sopenharmony_ci    unsigned char *A, B[16], *R;
105e1051a39Sopenharmony_ci    size_t i, j, t;
106e1051a39Sopenharmony_ci    inlen -= 8;
107e1051a39Sopenharmony_ci    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
108e1051a39Sopenharmony_ci        return 0;
109e1051a39Sopenharmony_ci    A = B;
110e1051a39Sopenharmony_ci    t = 6 * (inlen >> 3);
111e1051a39Sopenharmony_ci    memcpy(A, in, 8);
112e1051a39Sopenharmony_ci    memmove(out, in + 8, inlen);
113e1051a39Sopenharmony_ci    for (j = 0; j < 6; j++) {
114e1051a39Sopenharmony_ci        R = out + inlen - 8;
115e1051a39Sopenharmony_ci        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
116e1051a39Sopenharmony_ci            A[7] ^= (unsigned char)(t & 0xff);
117e1051a39Sopenharmony_ci            if (t > 0xff) {
118e1051a39Sopenharmony_ci                A[6] ^= (unsigned char)((t >> 8) & 0xff);
119e1051a39Sopenharmony_ci                A[5] ^= (unsigned char)((t >> 16) & 0xff);
120e1051a39Sopenharmony_ci                A[4] ^= (unsigned char)((t >> 24) & 0xff);
121e1051a39Sopenharmony_ci            }
122e1051a39Sopenharmony_ci            memcpy(B + 8, R, 8);
123e1051a39Sopenharmony_ci            block(B, B, key);
124e1051a39Sopenharmony_ci            memcpy(R, B + 8, 8);
125e1051a39Sopenharmony_ci        }
126e1051a39Sopenharmony_ci    }
127e1051a39Sopenharmony_ci    memcpy(iv, A, 8);
128e1051a39Sopenharmony_ci    return inlen;
129e1051a39Sopenharmony_ci}
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check.
132e1051a39Sopenharmony_ci *  The first block of plaintext has to match the supplied IV, otherwise an
133e1051a39Sopenharmony_ci *  error is returned.
134e1051a39Sopenharmony_ci *
135e1051a39Sopenharmony_ci *  @param[in]  key    Key value.
136e1051a39Sopenharmony_ci *  @param[out] iv     IV value to match against. Length = 8 bytes.
137e1051a39Sopenharmony_ci *                     NULL = use default_iv.
138e1051a39Sopenharmony_ci *  @param[out] out    Plaintext without IV.
139e1051a39Sopenharmony_ci *                     Minimal buffer length = (inlen - 8) bytes.
140e1051a39Sopenharmony_ci *                     Input and output buffers can overlap if block function
141e1051a39Sopenharmony_ci *                     supports that.
142e1051a39Sopenharmony_ci *  @param[in]  in     Ciphertext as n 64-bit blocks.
143e1051a39Sopenharmony_ci *  @param[in]  inlen  Length of in.
144e1051a39Sopenharmony_ci *  @param[in]  block  Block processing function.
145e1051a39Sopenharmony_ci *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
146e1051a39Sopenharmony_ci *                     or if inlen is not a multiple of 8
147e1051a39Sopenharmony_ci *                     or if IV doesn't match expected value.
148e1051a39Sopenharmony_ci *                     Output length otherwise.
149e1051a39Sopenharmony_ci */
150e1051a39Sopenharmony_cisize_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
151e1051a39Sopenharmony_ci                         unsigned char *out, const unsigned char *in,
152e1051a39Sopenharmony_ci                         size_t inlen, block128_f block)
153e1051a39Sopenharmony_ci{
154e1051a39Sopenharmony_ci    size_t ret;
155e1051a39Sopenharmony_ci    unsigned char got_iv[8];
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ci    ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block);
158e1051a39Sopenharmony_ci    if (ret == 0)
159e1051a39Sopenharmony_ci        return 0;
160e1051a39Sopenharmony_ci
161e1051a39Sopenharmony_ci    if (!iv)
162e1051a39Sopenharmony_ci        iv = default_iv;
163e1051a39Sopenharmony_ci    if (CRYPTO_memcmp(got_iv, iv, 8)) {
164e1051a39Sopenharmony_ci        OPENSSL_cleanse(out, ret);
165e1051a39Sopenharmony_ci        return 0;
166e1051a39Sopenharmony_ci    }
167e1051a39Sopenharmony_ci    return ret;
168e1051a39Sopenharmony_ci}
169e1051a39Sopenharmony_ci
170e1051a39Sopenharmony_ci/** Wrapping according to RFC 5649 section 4.1.
171e1051a39Sopenharmony_ci *
172e1051a39Sopenharmony_ci *  @param[in]  key    Key value.
173e1051a39Sopenharmony_ci *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
174e1051a39Sopenharmony_ci *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 15) bytes.
175e1051a39Sopenharmony_ci *                     Input and output buffers can overlap if block function
176e1051a39Sopenharmony_ci *                     supports that.
177e1051a39Sopenharmony_ci *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
178e1051a39Sopenharmony_ci *  @param[in]  inlen  Length of in.
179e1051a39Sopenharmony_ci *  @param[in]  block  Block processing function.
180e1051a39Sopenharmony_ci *  @return            0 if inlen is out of range [1, CRYPTO128_WRAP_MAX].
181e1051a39Sopenharmony_ci *                     Output length if wrapping succeeded.
182e1051a39Sopenharmony_ci */
183e1051a39Sopenharmony_cisize_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
184e1051a39Sopenharmony_ci                           unsigned char *out,
185e1051a39Sopenharmony_ci                           const unsigned char *in, size_t inlen,
186e1051a39Sopenharmony_ci                           block128_f block)
187e1051a39Sopenharmony_ci{
188e1051a39Sopenharmony_ci    /* n: number of 64-bit blocks in the padded key data
189e1051a39Sopenharmony_ci     *
190e1051a39Sopenharmony_ci     * If length of plain text is not a multiple of 8, pad the plain text octet
191e1051a39Sopenharmony_ci     * string on the right with octets of zeros, where final length is the
192e1051a39Sopenharmony_ci     * smallest multiple of 8 that is greater than length of plain text.
193e1051a39Sopenharmony_ci     * If length of plain text is a multiple of 8, then there is no padding. */
194e1051a39Sopenharmony_ci    const size_t blocks_padded = (inlen + 7) / 8; /* CEILING(m/8) */
195e1051a39Sopenharmony_ci    const size_t padded_len = blocks_padded * 8;
196e1051a39Sopenharmony_ci    const size_t padding_len = padded_len - inlen;
197e1051a39Sopenharmony_ci    /* RFC 5649 section 3: Alternative Initial Value */
198e1051a39Sopenharmony_ci    unsigned char aiv[8];
199e1051a39Sopenharmony_ci    int ret;
200e1051a39Sopenharmony_ci
201e1051a39Sopenharmony_ci    /* Section 1: use 32-bit fixed field for plaintext octet length */
202e1051a39Sopenharmony_ci    if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX)
203e1051a39Sopenharmony_ci        return 0;
204e1051a39Sopenharmony_ci
205e1051a39Sopenharmony_ci    /* Section 3: Alternative Initial Value */
206e1051a39Sopenharmony_ci    if (!icv)
207e1051a39Sopenharmony_ci        memcpy(aiv, default_aiv, 4);
208e1051a39Sopenharmony_ci    else
209e1051a39Sopenharmony_ci        memcpy(aiv, icv, 4);    /* Standard doesn't mention this. */
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ci    aiv[4] = (inlen >> 24) & 0xFF;
212e1051a39Sopenharmony_ci    aiv[5] = (inlen >> 16) & 0xFF;
213e1051a39Sopenharmony_ci    aiv[6] = (inlen >> 8) & 0xFF;
214e1051a39Sopenharmony_ci    aiv[7] = inlen & 0xFF;
215e1051a39Sopenharmony_ci
216e1051a39Sopenharmony_ci    if (padded_len == 8) {
217e1051a39Sopenharmony_ci        /*
218e1051a39Sopenharmony_ci         * Section 4.1 - special case in step 2: If the padded plaintext
219e1051a39Sopenharmony_ci         * contains exactly eight octets, then prepend the AIV and encrypt
220e1051a39Sopenharmony_ci         * the resulting 128-bit block using AES in ECB mode.
221e1051a39Sopenharmony_ci         */
222e1051a39Sopenharmony_ci        memmove(out + 8, in, inlen);
223e1051a39Sopenharmony_ci        memcpy(out, aiv, 8);
224e1051a39Sopenharmony_ci        memset(out + 8 + inlen, 0, padding_len);
225e1051a39Sopenharmony_ci        block(out, out, key);
226e1051a39Sopenharmony_ci        ret = 16;               /* AIV + padded input */
227e1051a39Sopenharmony_ci    } else {
228e1051a39Sopenharmony_ci        memmove(out, in, inlen);
229e1051a39Sopenharmony_ci        memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */
230e1051a39Sopenharmony_ci        ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block);
231e1051a39Sopenharmony_ci    }
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci    return ret;
234e1051a39Sopenharmony_ci}
235e1051a39Sopenharmony_ci
236e1051a39Sopenharmony_ci/** Unwrapping according to RFC 5649 section 4.2.
237e1051a39Sopenharmony_ci *
238e1051a39Sopenharmony_ci *  @param[in]  key    Key value.
239e1051a39Sopenharmony_ci *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
240e1051a39Sopenharmony_ci *  @param[out] out    Plaintext. Minimal buffer length = (inlen - 8) bytes.
241e1051a39Sopenharmony_ci *                     Input and output buffers can overlap if block function
242e1051a39Sopenharmony_ci *                     supports that.
243e1051a39Sopenharmony_ci *  @param[in]  in     Ciphertext as n 64-bit blocks.
244e1051a39Sopenharmony_ci *  @param[in]  inlen  Length of in.
245e1051a39Sopenharmony_ci *  @param[in]  block  Block processing function.
246e1051a39Sopenharmony_ci *  @return            0 if inlen is out of range [16, CRYPTO128_WRAP_MAX],
247e1051a39Sopenharmony_ci *                     or if inlen is not a multiple of 8
248e1051a39Sopenharmony_ci *                     or if IV and message length indicator doesn't match.
249e1051a39Sopenharmony_ci *                     Output length if unwrapping succeeded and IV matches.
250e1051a39Sopenharmony_ci */
251e1051a39Sopenharmony_cisize_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
252e1051a39Sopenharmony_ci                             unsigned char *out,
253e1051a39Sopenharmony_ci                             const unsigned char *in, size_t inlen,
254e1051a39Sopenharmony_ci                             block128_f block)
255e1051a39Sopenharmony_ci{
256e1051a39Sopenharmony_ci    /* n: number of 64-bit blocks in the padded key data */
257e1051a39Sopenharmony_ci    size_t n = inlen / 8 - 1;
258e1051a39Sopenharmony_ci    size_t padded_len;
259e1051a39Sopenharmony_ci    size_t padding_len;
260e1051a39Sopenharmony_ci    size_t ptext_len;
261e1051a39Sopenharmony_ci    /* RFC 5649 section 3: Alternative Initial Value */
262e1051a39Sopenharmony_ci    unsigned char aiv[8];
263e1051a39Sopenharmony_ci    static unsigned char zeros[8] = { 0x0 };
264e1051a39Sopenharmony_ci    size_t ret;
265e1051a39Sopenharmony_ci
266e1051a39Sopenharmony_ci    /* Section 4.2: Ciphertext length has to be (n+1) 64-bit blocks. */
267e1051a39Sopenharmony_ci    if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX)
268e1051a39Sopenharmony_ci        return 0;
269e1051a39Sopenharmony_ci
270e1051a39Sopenharmony_ci    if (inlen == 16) {
271e1051a39Sopenharmony_ci        /*
272e1051a39Sopenharmony_ci         * Section 4.2 - special case in step 1: When n=1, the ciphertext
273e1051a39Sopenharmony_ci         * contains exactly two 64-bit blocks and they are decrypted as a
274e1051a39Sopenharmony_ci         * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] |
275e1051a39Sopenharmony_ci         * C[1])
276e1051a39Sopenharmony_ci         */
277e1051a39Sopenharmony_ci        unsigned char buff[16];
278e1051a39Sopenharmony_ci
279e1051a39Sopenharmony_ci        block(in, buff, key);
280e1051a39Sopenharmony_ci        memcpy(aiv, buff, 8);
281e1051a39Sopenharmony_ci        /* Remove AIV */
282e1051a39Sopenharmony_ci        memcpy(out, buff + 8, 8);
283e1051a39Sopenharmony_ci        padded_len = 8;
284e1051a39Sopenharmony_ci        OPENSSL_cleanse(buff, inlen);
285e1051a39Sopenharmony_ci    } else {
286e1051a39Sopenharmony_ci        padded_len = inlen - 8;
287e1051a39Sopenharmony_ci        ret = crypto_128_unwrap_raw(key, aiv, out, in, inlen, block);
288e1051a39Sopenharmony_ci        if (padded_len != ret) {
289e1051a39Sopenharmony_ci            OPENSSL_cleanse(out, inlen);
290e1051a39Sopenharmony_ci            return 0;
291e1051a39Sopenharmony_ci        }
292e1051a39Sopenharmony_ci    }
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_ci    /*
295e1051a39Sopenharmony_ci     * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a
296e1051a39Sopenharmony_ci     * user-supplied value can be used (even if standard doesn't mention
297e1051a39Sopenharmony_ci     * this).
298e1051a39Sopenharmony_ci     */
299e1051a39Sopenharmony_ci    if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4))
300e1051a39Sopenharmony_ci        || (icv && CRYPTO_memcmp(aiv, icv, 4))) {
301e1051a39Sopenharmony_ci        OPENSSL_cleanse(out, inlen);
302e1051a39Sopenharmony_ci        return 0;
303e1051a39Sopenharmony_ci    }
304e1051a39Sopenharmony_ci
305e1051a39Sopenharmony_ci    /*
306e1051a39Sopenharmony_ci     * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len =
307e1051a39Sopenharmony_ci     * LSB(32,AIV).
308e1051a39Sopenharmony_ci     */
309e1051a39Sopenharmony_ci
310e1051a39Sopenharmony_ci    ptext_len =   ((unsigned int)aiv[4] << 24)
311e1051a39Sopenharmony_ci                | ((unsigned int)aiv[5] << 16)
312e1051a39Sopenharmony_ci                | ((unsigned int)aiv[6] <<  8)
313e1051a39Sopenharmony_ci                |  (unsigned int)aiv[7];
314e1051a39Sopenharmony_ci    if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) {
315e1051a39Sopenharmony_ci        OPENSSL_cleanse(out, inlen);
316e1051a39Sopenharmony_ci        return 0;
317e1051a39Sopenharmony_ci    }
318e1051a39Sopenharmony_ci
319e1051a39Sopenharmony_ci    /*
320e1051a39Sopenharmony_ci     * Check that the rightmost padding_len octets of the output data are
321e1051a39Sopenharmony_ci     * zero.
322e1051a39Sopenharmony_ci     */
323e1051a39Sopenharmony_ci    padding_len = padded_len - ptext_len;
324e1051a39Sopenharmony_ci    if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) {
325e1051a39Sopenharmony_ci        OPENSSL_cleanse(out, inlen);
326e1051a39Sopenharmony_ci        return 0;
327e1051a39Sopenharmony_ci    }
328e1051a39Sopenharmony_ci
329e1051a39Sopenharmony_ci    /* Section 4.2 step 3: Remove padding */
330e1051a39Sopenharmony_ci    return ptext_len;
331e1051a39Sopenharmony_ci}
332