crypto/fipsmodule/modes/cfb.c
Go to the documentation of this file.
1 /* ====================================================================
2  * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  * software must display the following acknowledgment:
18  * "This product includes software developed by the OpenSSL Project
19  * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  * endorse or promote products derived from this software without
23  * prior written permission. For written permission, please contact
24  * openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  * nor may "OpenSSL" appear in their names without prior written
28  * permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  * acknowledgment:
32  * "This product includes software developed by the OpenSSL Project
33  * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ==================================================================== */
48 
49 #include <openssl/type_check.h>
50 
51 #include <assert.h>
52 #include <string.h>
53 
54 #include "internal.h"
55 
56 
57 OPENSSL_STATIC_ASSERT(16 % sizeof(size_t) == 0,
58  "block cannot be divided into size_t");
59 
61  const AES_KEY *key, uint8_t ivec[16], unsigned *num,
62  int enc, block128_f block) {
63  assert(in && out && key && ivec && num);
64 
65  unsigned n = *num;
66 
67  if (enc) {
68  while (n && len) {
69  *(out++) = ivec[n] ^= *(in++);
70  --len;
71  n = (n + 1) % 16;
72  }
73  while (len >= 16) {
74  (*block)(ivec, ivec, key);
75  for (; n < 16; n += sizeof(crypto_word_t)) {
76  crypto_word_t tmp =
78  CRYPTO_store_word_le(ivec + n, tmp);
80  }
81  len -= 16;
82  out += 16;
83  in += 16;
84  n = 0;
85  }
86  if (len) {
87  (*block)(ivec, ivec, key);
88  while (len--) {
89  out[n] = ivec[n] ^= in[n];
90  ++n;
91  }
92  }
93  *num = n;
94  return;
95  } else {
96  while (n && len) {
97  uint8_t c;
98  *(out++) = ivec[n] ^ (c = *(in++));
99  ivec[n] = c;
100  --len;
101  n = (n + 1) % 16;
102  }
103  while (len >= 16) {
104  (*block)(ivec, ivec, key);
105  for (; n < 16; n += sizeof(crypto_word_t)) {
106  crypto_word_t t = CRYPTO_load_word_le(in + n);
108  CRYPTO_store_word_le(ivec + n, t);
109  }
110  len -= 16;
111  out += 16;
112  in += 16;
113  n = 0;
114  }
115  if (len) {
116  (*block)(ivec, ivec, key);
117  while (len--) {
118  uint8_t c;
119  out[n] = ivec[n] ^ (c = in[n]);
120  ivec[n] = c;
121  ++n;
122  }
123  }
124  *num = n;
125  return;
126  }
127 }
128 
129 
130 /* This expects a single block of size nbits for both in and out. Note that
131  it corrupts any extra bits in the last byte of out */
132 static void cfbr_encrypt_block(const uint8_t *in, uint8_t *out, unsigned nbits,
133  const AES_KEY *key, uint8_t ivec[16], int enc,
134  block128_f block) {
135  int n, rem, num;
136  uint8_t ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't use) one
137  byte off the end */
138 
139  if (nbits <= 0 || nbits > 128) {
140  return;
141  }
142 
143  // fill in the first half of the new IV with the current IV
144  OPENSSL_memcpy(ovec, ivec, 16);
145  // construct the new IV
146  (*block)(ivec, ivec, key);
147  num = (nbits + 7) / 8;
148  if (enc) {
149  // encrypt the input
150  for (n = 0; n < num; ++n) {
151  out[n] = (ovec[16 + n] = in[n] ^ ivec[n]);
152  }
153  } else {
154  // decrypt the input
155  for (n = 0; n < num; ++n) {
156  out[n] = (ovec[16 + n] = in[n]) ^ ivec[n];
157  }
158  }
159  // shift ovec left...
160  rem = nbits % 8;
161  num = nbits / 8;
162  if (rem == 0) {
163  OPENSSL_memcpy(ivec, ovec + num, 16);
164  } else {
165  for (n = 0; n < 16; ++n) {
166  ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem);
167  }
168  }
169 
170  // it is not necessary to cleanse ovec, since the IV is not secret
171 }
172 
173 // N.B. This expects the input to be packed, MS bit first
175  const AES_KEY *key, uint8_t ivec[16],
176  unsigned *num, int enc, block128_f block) {
177  size_t n;
178  uint8_t c[1], d[1];
179 
180  assert(in && out && key && ivec && num);
181  assert(*num == 0);
182 
183  for (n = 0; n < bits; ++n) {
184  c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
185  cfbr_encrypt_block(c, d, 1, key, ivec, enc, block);
186  out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) |
187  ((d[0] & 0x80) >> (unsigned int)(n % 8));
188  }
189 }
190 
191 void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
192  size_t length, const AES_KEY *key,
193  unsigned char ivec[16], unsigned *num, int enc,
194  block128_f block) {
195  size_t n;
196 
197  assert(in && out && key && ivec && num);
198  assert(*num == 0);
199 
200  for (n = 0; n < length; ++n) {
201  cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
202  }
203 }
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
string.h
CRYPTO_cfb128_1_encrypt
void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits, const AES_KEY *key, uint8_t ivec[16], unsigned *num, int enc, block128_f block)
Definition: crypto/fipsmodule/modes/cfb.c:174
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
CRYPTO_store_word_le
static void CRYPTO_store_word_le(void *out, crypto_word_t v)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:888
CRYPTO_cfb128_encrypt
void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, uint8_t ivec[16], unsigned *num, int enc, block128_f block)
Definition: crypto/fipsmodule/modes/cfb.c:60
block
Block * block
Definition: protobuf/src/google/protobuf/descriptor.cc:1041
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
xds_interop_client.int
int
Definition: xds_interop_client.py:113
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
bits
OPENSSL_EXPORT ASN1_BIT_STRING * bits
Definition: x509v3.h:482
CRYPTO_cfb128_8_encrypt
void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[16], unsigned *num, int enc, block128_f block)
Definition: crypto/fipsmodule/modes/cfb.c:191
d
static const fe d
Definition: curve25519_tables.h:19
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
internal.h
key
const char * key
Definition: hpack_parser_table.cc:164
OPENSSL_STATIC_ASSERT
OPENSSL_STATIC_ASSERT(16 % sizeof(size_t)==0, "block cannot be divided into size_t")
xds_manager.num
num
Definition: xds_manager.py:56
cfbr_encrypt_block
static void cfbr_encrypt_block(const uint8_t *in, uint8_t *out, unsigned nbits, const AES_KEY *key, uint8_t ivec[16], int enc, block128_f block)
Definition: crypto/fipsmodule/modes/cfb.c:132
type_check.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
aes_key_st
Definition: aes.h:72
block128_f
void(* block128_f)(const uint8_t in[16], uint8_t out[16], const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h:76
CRYPTO_load_word_le
static crypto_word_t CRYPTO_load_word_le(const void *in)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:882


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:52