сб, 27 июн. 2020 г. в 22:37, Dmitry Baryshkov <dbarysh...@gmail.com>: > > 64-bit ciphers are old, but it would be good to use common code for > their implementations.
Gracious ping for this patchset. > > Signed-off-by: Dmitry Baryshkov <dbarysh...@gmail.com> > --- > src/lib/libcrypto/modes/cbc64.c | 202 ++++++++++++++++++++++++++++++++ > src/lib/libcrypto/modes/cfb64.c | 169 ++++++++++++++++++++++++++ > src/lib/libcrypto/modes/ctr64.c | 174 +++++++++++++++++++++++++++ > src/lib/libcrypto/modes/modes.h | 26 ++++ > src/lib/libcrypto/modes/ofb64.c | 119 +++++++++++++++++++ > 5 files changed, 690 insertions(+) > create mode 100644 src/lib/libcrypto/modes/cbc64.c > create mode 100644 src/lib/libcrypto/modes/cfb64.c > create mode 100644 src/lib/libcrypto/modes/ctr64.c > create mode 100644 src/lib/libcrypto/modes/ofb64.c > > diff --git a/src/lib/libcrypto/modes/cbc64.c b/src/lib/libcrypto/modes/cbc64.c > new file mode 100644 > index 000000000000..ec65ac5d3468 > --- /dev/null > +++ b/src/lib/libcrypto/modes/cbc64.c > @@ -0,0 +1,202 @@ > +/* $OpenBSD: cbc64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */ > +/* ==================================================================== > + * Copyright (c) 2008 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 > + * openssl-c...@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. > + * ==================================================================== > + * > + */ > + > +#include <openssl/crypto.h> > +#include "modes_lcl.h" > +#include <string.h> > + > +#ifndef MODES_DEBUG > +# ifndef NDEBUG > +# define NDEBUG > +# endif > +#endif > + > +#undef STRICT_ALIGNMENT > +#ifdef __STRICT_ALIGNMENT > +#define STRICT_ALIGNMENT 1 > +#else > +#define STRICT_ALIGNMENT 0 > +#endif > + > +void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], block64_f block) > +{ > + size_t n; > + const unsigned char *iv = ivec; > + > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (STRICT_ALIGNMENT && > + ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { > + while (len>=8) { > + for(n=0; n<8; ++n) > + out[n] = in[n] ^ iv[n]; > + (*block)(out, out, key); > + iv = out; > + len -= 8; > + in += 8; > + out += 8; > + } > + } else { > + while (len>=8) { > + for(n=0; n<8; n+=sizeof(size_t)) > + *(size_t*)(out+n) = > + *(size_t*)(in+n) ^ *(size_t*)(iv+n); > + (*block)(out, out, key); > + iv = out; > + len -= 8; > + in += 8; > + out += 8; > + } > + } > +#endif > + while (len) { > + for(n=0; n<8 && n<len; ++n) > + out[n] = in[n] ^ iv[n]; > + for(; n<8; ++n) > + out[n] = iv[n]; > + (*block)(out, out, key); > + iv = out; > + if (len<=8) break; > + len -= 8; > + in += 8; > + out += 8; > + } > + memcpy(ivec,iv,8); > +} > + > +void CRYPTO_cbc64_decrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], block64_f block) > +{ > + size_t n; > + union { size_t t[8/sizeof(size_t)]; unsigned char c[8]; } tmp; > + > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (in != out) { > + const unsigned char *iv = ivec; > + > + if (STRICT_ALIGNMENT && > + ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != > 0) { > + while (len>=8) { > + (*block)(in, out, key); > + for(n=0; n<8; ++n) > + out[n] ^= iv[n]; > + iv = in; > + len -= 8; > + in += 8; > + out += 8; > + } > + } else if (8%sizeof(size_t) == 0) { /* always true */ > + while (len>=8) { > + size_t *out_t=(size_t *)out, *iv_t=(size_t > *)iv; > + > + (*block)(in, out, key); > + for(n=0; n<8/sizeof(size_t); n++) > + out_t[n] ^= iv_t[n]; > + iv = in; > + len -= 8; > + in += 8; > + out += 8; > + } > + } > + memcpy(ivec,iv,8); > + } else { > + if (STRICT_ALIGNMENT && > + ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != > 0) { > + unsigned char c; > + while (len>=8) { > + (*block)(in, tmp.c, key); > + for(n=0; n<8; ++n) { > + c = in[n]; > + out[n] = tmp.c[n] ^ ivec[n]; > + ivec[n] = c; > + } > + len -= 8; > + in += 8; > + out += 8; > + } > + } else if (8%sizeof(size_t) == 0) { /* always true */ > + while (len>=8) { > + size_t c, *out_t=(size_t *)out, > *ivec_t=(size_t *)ivec; > + const size_t *in_t=(const size_t *)in; > + > + (*block)(in, tmp.c, key); > + for(n=0; n<8/sizeof(size_t); n++) { > + c = in_t[n]; > + out_t[n] = tmp.t[n] ^ ivec_t[n]; > + ivec_t[n] = c; > + } > + len -= 8; > + in += 8; > + out += 8; > + } > + } > + } > +#endif > + while (len) { > + unsigned char c; > + (*block)(in, tmp.c, key); > + for(n=0; n<8 && n<len; ++n) { > + c = in[n]; > + out[n] = tmp.c[n] ^ ivec[n]; > + ivec[n] = c; > + } > + if (len<=8) { > + for (; n<8; ++n) > + ivec[n] = in[n]; > + break; > + } > + len -= 8; > + in += 8; > + out += 8; > + } > +} > diff --git a/src/lib/libcrypto/modes/cfb64.c b/src/lib/libcrypto/modes/cfb64.c > new file mode 100644 > index 000000000000..f335fa39c4ea > --- /dev/null > +++ b/src/lib/libcrypto/modes/cfb64.c > @@ -0,0 +1,169 @@ > +/* $OpenBSD: cfb64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */ > +/* ==================================================================== > + * Copyright (c) 2008 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 > + * openssl-c...@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. > + * ==================================================================== > + * > + */ > + > +#include <openssl/crypto.h> > +#include "modes_lcl.h" > +#include <string.h> > + > +#ifndef MODES_DEBUG > +# ifndef NDEBUG > +# define NDEBUG > +# endif > +#endif > + > +/* The input and output encrypted as though 64bit cfb mode is being > + * used. The extra state information to record how much of the > + * 64bit block we have used is contained in *num; > + */ > +void CRYPTO_cfb64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], int *num, > + int enc, block64_f block) > +{ > + unsigned int n; > + size_t l = 0; > + > + n = *num; > + > + if (enc) { > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (8%sizeof(size_t) == 0) do { /* always true actually */ > + while (n && len) { > + *(out++) = ivec[n] ^= *(in++); > + --len; > + n = (n+1) % 8; > + } > +#ifdef __STRICT_ALIGNMENT > + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) > + break; > +#endif > + while (len>=8) { > + (*block)(ivec, ivec, key); > + for (; n<8; n+=sizeof(size_t)) { > + *(size_t*)(out+n) = > + *(size_t*)(ivec+n) ^= *(size_t*)(in+n); > + } > + len -= 8; > + out += 8; > + in += 8; > + n = 0; > + } > + if (len) { > + (*block)(ivec, ivec, key); > + while (len--) { > + out[n] = ivec[n] ^= in[n]; > + ++n; > + } > + } > + *num = n; > + return; > + } while (0); > + /* the rest would be commonly eliminated by x86* compiler */ > +#endif > + while (l<len) { > + if (n == 0) { > + (*block)(ivec, ivec, key); > + } > + out[l] = ivec[n] ^= in[l]; > + ++l; > + n = (n+1) % 8; > + } > + *num = n; > + } else { > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (8%sizeof(size_t) == 0) do { /* always true actually */ > + while (n && len) { > + unsigned char c; > + *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c; > + --len; > + n = (n+1) % 8; > + } > +#ifdef __STRICT_ALIGNMENT > + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) > + break; > +#endif > + while (len>=8) { > + (*block)(ivec, ivec, key); > + for (; n<8; n+=sizeof(size_t)) { > + size_t t = *(size_t*)(in+n); > + *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t; > + *(size_t*)(ivec+n) = t; > + } > + len -= 8; > + out += 8; > + in += 8; > + n = 0; > + } > + if (len) { > + (*block)(ivec, ivec, key); > + while (len--) { > + unsigned char c; > + out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c; > + ++n; > + } > + } > + *num = n; > + return; > + } while (0); > + /* the rest would be commonly eliminated by x86* compiler */ > +#endif > + while (l<len) { > + unsigned char c; > + if (n == 0) { > + (*block)(ivec, ivec, key); > + } > + out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; > + ++l; > + n = (n+1) % 8; > + } > + *num=n; > + } > +} > diff --git a/src/lib/libcrypto/modes/ctr64.c b/src/lib/libcrypto/modes/ctr64.c > new file mode 100644 > index 000000000000..e1743cb91193 > --- /dev/null > +++ b/src/lib/libcrypto/modes/ctr64.c > @@ -0,0 +1,174 @@ > +/* $OpenBSD: ctr64.c,v 1.7 2017/08/13 17:46:24 bcook Exp $ */ > +/* ==================================================================== > + * Copyright (c) 2008 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 > + * openssl-c...@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. > + * ==================================================================== > + * > + */ > + > +#include <openssl/crypto.h> > +#include "modes_lcl.h" > +#include <string.h> > + > +#ifndef MODES_DEBUG > +# ifndef NDEBUG > +# define NDEBUG > +# endif > +#endif > +#include <assert.h> > + > +/* NOTE: the IV/counter CTR mode is big-endian. The code itself > + * is endian-neutral. */ > + > +/* increment counter (64-bit int) by 1 */ > +static void ctr64_inc(unsigned char *counter) { > + u32 n=8; > + u8 c; > + > + do { > + --n; > + c = counter[n]; > + ++c; > + counter[n] = c; > + if (c) return; > + } while (n); > +} > + > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > +static void > +ctr64_inc_aligned(unsigned char *counter) > +{ > +#if BYTE_ORDER == LITTLE_ENDIAN > + ctr64_inc(counter); > +#else > + size_t *data, c, n; > + data = (size_t *)counter; > + n = 8 / sizeof(size_t); > + do { > + --n; > + c = data[n]; > + ++c; > + data[n] = c; > + if (c) > + return; > + } while (n); > +#endif > +} > +#endif > + > +/* The input encrypted as though 64bit counter mode is being > + * used. The extra state information to record how much of the > + * 64bit block we have used is contained in *num, and the > + * encrypted counter is kept in ecount_buf. Both *num and > + * ecount_buf must be initialised with zeros before the first > + * call to CRYPTO_ctr64_encrypt(). > + * > + * This algorithm assumes that the counter is in the x lower bits > + * of the IV (ivec), and that the application has full control over > + * overflow and the rest of the IV. This implementation takes NO > + * responsability for checking that the counter doesn't overflow > + * into the rest of the IV when incremented. > + */ > +void CRYPTO_ctr64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], unsigned char ecount_buf[8], > + unsigned int *num, block64_f block) > +{ > + unsigned int n; > + size_t l=0; > + > + assert(*num < 8); > + > + n = *num; > + > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (8%sizeof(size_t) == 0) do { /* always true actually */ > + while (n && len) { > + *(out++) = *(in++) ^ ecount_buf[n]; > + --len; > + n = (n+1) % 8; > + } > + > +#ifdef __STRICT_ALIGNMENT > + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) > + break; > +#endif > + while (len>=8) { > + (*block)(ivec, ecount_buf, key); > + ctr64_inc_aligned(ivec); > + for (; n<8; n+=sizeof(size_t)) > + *(size_t *)(out+n) = > + *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n); > + len -= 8; > + out += 8; > + in += 8; > + n = 0; > + } > + if (len) { > + (*block)(ivec, ecount_buf, key); > + ctr64_inc_aligned(ivec); > + while (len--) { > + out[n] = in[n] ^ ecount_buf[n]; > + ++n; > + } > + } > + *num = n; > + return; > + } while(0); > + /* the rest would be commonly eliminated by x86* compiler */ > +#endif > + while (l<len) { > + if (n==0) { > + (*block)(ivec, ecount_buf, key); > + ctr64_inc(ivec); > + } > + out[l] = in[l] ^ ecount_buf[n]; > + ++l; > + n = (n+1) % 8; > + } > + > + *num=n; > +} > diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h > index 67ec7518d621..2344e944ea31 100644 > --- a/src/lib/libcrypto/modes/modes.h > +++ b/src/lib/libcrypto/modes/modes.h > @@ -139,6 +139,32 @@ typedef struct xts128_context XTS128_CONTEXT; > int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char > iv[16], > const unsigned char *inp, unsigned char *out, size_t len, int enc); > > +typedef void (*block64_f)(const unsigned char in[8], > + unsigned char out[8], > + const void *key); > + > +void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], block64_f block); > +void CRYPTO_cbc64_decrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], block64_f block); > + > +void CRYPTO_ctr64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], unsigned char ecount_buf[8], > + unsigned int *num, block64_f block); > + > +void CRYPTO_ofb64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], int *num, > + block64_f block); > + > +void CRYPTO_cfb64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], int *num, > + int enc, block64_f block); > + > #ifdef __cplusplus > } > #endif > diff --git a/src/lib/libcrypto/modes/ofb64.c b/src/lib/libcrypto/modes/ofb64.c > new file mode 100644 > index 000000000000..8368811cecbf > --- /dev/null > +++ b/src/lib/libcrypto/modes/ofb64.c > @@ -0,0 +1,119 @@ > +/* $OpenBSD: ofb64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */ > +/* ==================================================================== > + * Copyright (c) 2008 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 > + * openssl-c...@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. > + * ==================================================================== > + * > + */ > + > +#include <openssl/crypto.h> > +#include "modes_lcl.h" > +#include <string.h> > + > +#ifndef MODES_DEBUG > +# ifndef NDEBUG > +# define NDEBUG > +# endif > +#endif > + > +/* The input and output encrypted as though 64bit ofb mode is being > + * used. The extra state information to record how much of the > + * 64bit block we have used is contained in *num; > + */ > +void CRYPTO_ofb64_encrypt(const unsigned char *in, unsigned char *out, > + size_t len, const void *key, > + unsigned char ivec[8], int *num, > + block64_f block) > +{ > + unsigned int n; > + size_t l=0; > + > + n = *num; > + > +#if !defined(OPENSSL_SMALL_FOOTPRINT) > + if (8%sizeof(size_t) == 0) do { /* always true actually */ > + while (n && len) { > + *(out++) = *(in++) ^ ivec[n]; > + --len; > + n = (n+1) % 8; > + } > +#ifdef __STRICT_ALIGNMENT > + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) > + break; > +#endif > + while (len>=8) { > + (*block)(ivec, ivec, key); > + for (; n<8; n+=sizeof(size_t)) > + *(size_t*)(out+n) = > + *(size_t*)(in+n) ^ *(size_t*)(ivec+n); > + len -= 8; > + out += 8; > + in += 8; > + n = 0; > + } > + if (len) { > + (*block)(ivec, ivec, key); > + while (len--) { > + out[n] = in[n] ^ ivec[n]; > + ++n; > + } > + } > + *num = n; > + return; > + } while(0); > + /* the rest would be commonly eliminated by x86* compiler */ > +#endif > + while (l<len) { > + if (n==0) { > + (*block)(ivec, ivec, key); > + } > + out[l] = in[l] ^ ivec[n]; > + ++l; > + n = (n+1) % 8; > + } > + > + *num=n; > +} > -- > 2.27.0 > -- With best wishes Dmitry