Coverage Report

Created: 2024-11-25 06:27

/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
3.77k
#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
1.31k
{
72
1.31k
  assert(!(length % block_size));
73
74
1.31k
  if (!length)
75
0
    return;
76
77
1.31k
  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
1.31k
  else
89
1.31k
    {
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
1.31k
      TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT);
99
1.31k
      TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
100
101
1.31k
      size_t buffer_size;
102
103
1.31k
      if (length <= CBC_BUFFER_LIMIT)
104
93
  buffer_size = length;
105
1.22k
      else
106
1.22k
  buffer_size
107
1.22k
    = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);
108
109
1.31k
      TMP_ALLOC(buffer, buffer_size);
110
1.31k
      TMP_ALLOC(initial_iv, block_size);
111
112
3.77k
      for ( ; length > buffer_size; length -= buffer_size, dst += buffer_size)
113
2.45k
  {
114
2.45k
    f(ctx, buffer_size, buffer, dst);
115
2.45k
    memcpy(initial_iv, iv, block_size);
116
2.45k
    memcpy(iv, dst + buffer_size - block_size, block_size);
117
2.45k
    memxor3(dst + block_size, buffer + block_size, dst,
118
2.45k
      buffer_size - block_size);
119
2.45k
    memxor3(dst, buffer, initial_iv, block_size);
120
2.45k
  }
121
122
1.31k
      f(ctx, length, buffer, dst);
123
1.31k
      memcpy(initial_iv, iv, block_size);
124
      /* Copies last block */
125
1.31k
      memcpy(iv, dst + length - block_size, block_size);
126
      /* Writes all but first block, reads all but last block. */
127
1.31k
      memxor3(dst + block_size, buffer + block_size, dst,
128
1.31k
        length - block_size);
129
      /* Writes first block. */
130
1.31k
      memxor3(dst, buffer, initial_iv, block_size);
131
1.31k
    }
132
1.31k
}
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