Coverage Report

Created: 2023-03-26 07:33

/src/nettle/cbc.c
Line
Count
Source (jump to first uncovered line)
1
/* cbc.c
2
3
   Cipher block chaining mode.
4
5
   Copyright (C) 2001, 2011 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
12
     * the GNU Lesser General Public License as published by the Free
13
       Software Foundation; either version 3 of the License, or (at your
14
       option) any later version.
15
16
   or
17
18
     * the GNU General Public License as published by the Free
19
       Software Foundation; either version 2 of the License, or (at your
20
       option) any later version.
21
22
   or both in parallel, as here.
23
24
   GNU Nettle is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
   General Public License for more details.
28
29
   You should have received copies of the GNU General Public License and
30
   the GNU Lesser General Public License along with this program.  If
31
   not, see http://www.gnu.org/licenses/.
32
*/
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <assert.h>
39
#include <stdlib.h>
40
#include <string.h>
41
42
#include "cbc.h"
43
44
#include "memxor.h"
45
#include "nettle-internal.h"
46
47
void
48
cbc_encrypt(const void *ctx, nettle_cipher_func *f,
49
      size_t block_size, uint8_t *iv,
50
      size_t length, uint8_t *dst,
51
      const uint8_t *src)
52
0
{
53
0
  assert(!(length % block_size));
54
55
0
  for ( ; length; length -= block_size, src += block_size, dst += block_size)
56
0
    {
57
0
      memxor(iv, src, block_size);
58
0
      f(ctx, block_size, dst, iv);
59
0
      memcpy(iv, dst, block_size);
60
0
    }
61
0
}
62
63
/* Don't allocate any more space than this on the stack */
64
0
#define CBC_BUFFER_LIMIT 512
65
66
void
67
cbc_decrypt(const void *ctx, nettle_cipher_func *f,
68
      size_t block_size, uint8_t *iv,
69
      size_t length, uint8_t *dst,
70
      const uint8_t *src)
71
0
{
72
0
  assert(!(length % block_size));
73
74
0
  if (!length)
75
0
    return;
76
77
0
  if (src != dst)
78
0
    {
79
      /* Decrypt in ECB mode */
80
0
      f(ctx, length, dst, src);
81
82
      /* XOR the cryptotext, shifted one block */
83
0
      memxor(dst, iv, block_size);
84
0
      memxor(dst + block_size, src, length - block_size);
85
0
      memcpy(iv, src + length - block_size, block_size);
86
0
    }
87
88
0
  else
89
0
    {
90
      /* For in-place CBC, we decrypt into a temporary buffer of size
91
       * at most CBC_BUFFER_LIMIT, and process that amount of data at
92
       * a time. */
93
      
94
      /* NOTE: We assume that block_size <= CBC_BUFFER_LIMIT, and we
95
   depend on memxor3 working from the end of the area, allowing
96
   certain overlapping operands. */ 
97
98
0
      TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT);
99
0
      TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
100
101
0
      size_t buffer_size;
102
103
0
      if (length <= CBC_BUFFER_LIMIT)
104
0
  buffer_size = length;
105
0
      else
106
0
  buffer_size
107
0
    = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);
108
109
0
      TMP_ALLOC(buffer, buffer_size);
110
0
      TMP_ALLOC(initial_iv, block_size);
111
112
0
      for ( ; length > buffer_size; length -= buffer_size, dst += buffer_size)
113
0
  {
114
0
    f(ctx, buffer_size, buffer, dst);
115
0
    memcpy(initial_iv, iv, block_size);
116
0
    memcpy(iv, dst + buffer_size - block_size, block_size);
117
0
    memxor3(dst + block_size, buffer + block_size, dst,
118
0
      buffer_size - block_size);
119
0
    memxor3(dst, buffer, initial_iv, block_size);
120
0
  }
121
122
0
      f(ctx, length, buffer, dst);
123
0
      memcpy(initial_iv, iv, block_size);
124
      /* Copies last block */
125
0
      memcpy(iv, dst + length - block_size, block_size);
126
      /* Writes all but first block, reads all but last block. */
127
0
      memxor3(dst + block_size, buffer + block_size, dst,
128
0
        length - block_size);
129
      /* Writes first block. */
130
0
      memxor3(dst, buffer, initial_iv, block_size);
131
0
    }
132
0
}
133
134
#if 0
135
#include "twofish.h"
136
#include "aes.h"
137
138
static void foo(void)
139
{
140
  struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
141
  uint8_t src[TWOFISH_BLOCK_SIZE];
142
  uint8_t dst[TWOFISH_BLOCK_SIZE];
143
  
144
  CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
145
146
  /* Should result in a warning */
147
  CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
148
  
149
}
150
151
static void foo2(void)
152
{
153
  struct twofish_ctx ctx;
154
  uint8_t iv[TWOFISH_BLOCK_SIZE];
155
  uint8_t src[TWOFISH_BLOCK_SIZE];
156
  uint8_t dst[TWOFISH_BLOCK_SIZE];
157
  
158
  CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
159
  /* Should result in a warning */
160
  CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
161
}
162
163
#endif