File Coverage

inc/matrixssl-3-9-3-open/crypto/symmetric/aesCBC.c
Criterion Covered Total %
statement 29 33 87.8
branch 15 16 93.7
condition n/a
subroutine n/a
pod n/a
total 44 49 89.8


line stmt bran cond sub pod time code
1             /**
2             * @file aesCBC.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * AES CBC block cipher implementation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             #ifdef USE_MATRIX_AES_CBC
38              
39             /******************************************************************************/
40              
41 0           void psAesClearCBC(psAesCbc_t *ctx)
42             {
43             /* Only need to clear block if it's implemented externally, Matrix block
44             is part of CipherContext and will be cleared below */
45             # ifndef USE_MATRIX_AES_BLOCK
46             psAesClearBlockKey(&ctx->key);
47             # endif
48 0           memset_s(ctx, sizeof(psAesCbc_t), 0x0, sizeof(psAesCbc_t));
49 0           }
50              
51             /******************************************************************************/
52             /*
53             Software implementation of AES CBC APIs
54             */
55 4           int32_t psAesInitCBC(psAesCbc_t *ctx,
56             const unsigned char IV[AES_IVLEN],
57             const unsigned char key[AES_MAXKEYLEN], uint8_t keylen,
58             uint32_t flags)
59             {
60             int32_t x, err;
61              
62             # ifdef CRYPTO_ASSERT
63             if (IV == NULL || key == NULL || ctx == NULL ||
64             !(flags & (PS_AES_ENCRYPT | PS_AES_DECRYPT)))
65             {
66              
67             psTraceCrypto("psAesInitCBC arg fail\n");
68             return PS_ARG_FAIL;
69             }
70             # endif
71 4 50         if ((err = psAesInitBlockKey(&ctx->key, key, keylen, flags)) != PS_SUCCESS)
72             {
73 0           return err;
74             }
75 68 100         for (x = 0; x < AES_BLOCKLEN; x++)
76             {
77 64           ctx->IV[x] = IV[x];
78             }
79 4           return PS_SUCCESS;
80             }
81              
82             /******************************************************************************/
83              
84 5           void psAesEncryptCBC(psAesCbc_t *ctx,
85             const unsigned char *pt, unsigned char *ct,
86             uint32_t len)
87             {
88             uint32_t i, j;
89             unsigned char tmp[AES_BLOCKLEN];
90              
91             # ifdef CRYPTO_ASSERT
92             if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0 ||
93             ctx->key.type != PS_AES_ENCRYPT)
94             {
95              
96             psTraceCrypto("Bad parameters to psAesEncryptCBC\n");
97             return;
98             }
99             # endif
100 17 100         for (i = 0; i < len; i += AES_BLOCKLEN)
101             {
102             /* xor IV against plaintext */
103 204 100         for (j = 0; j < AES_BLOCKLEN; j++)
104             {
105 192           tmp[j] = pt[j] ^ ctx->IV[j];
106             }
107              
108 12           psAesEncryptBlock(&ctx->key, tmp, ct);
109              
110             /* store IV [ciphertext] for a future block */
111 204 100         for (j = 0; j < AES_BLOCKLEN; j++)
112             {
113 192           ctx->IV[j] = ct[j];
114             }
115 12           ct += AES_BLOCKLEN;
116 12           pt += AES_BLOCKLEN;
117             }
118              
119 5           memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp));
120 5           }
121              
122             /******************************************************************************/
123              
124 3           void psAesDecryptCBC(psAesCbc_t *ctx,
125             const unsigned char *ct, unsigned char *pt,
126             uint32_t len)
127             {
128             uint32_t i, j;
129             unsigned char tmp[AES_BLOCKLEN], tmp2[AES_BLOCKLEN];
130              
131             # ifdef CRYPTO_ASSERT
132             if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0 ||
133             ctx->key.type != PS_AES_DECRYPT)
134             {
135              
136             psTraceCrypto("Bad parameters to psAesDecryptCBC\n");
137             return;
138             }
139             # endif
140              
141 15 100         for (i = 0; i < len; i += AES_BLOCKLEN)
142             {
143 12           psAesDecryptBlock(&ctx->key, ct, tmp);
144             /* xor IV against the plaintext of the previous step */
145 204 100         for (j = 0; j < AES_BLOCKLEN; j++)
146             {
147             /* copy CT in case ct == pt */
148 192           tmp2[j] = ct[j];
149             /* actually decrypt the byte */
150 192           pt[j] = tmp[j] ^ ctx->IV[j];
151             }
152             /* replace IV with this current ciphertext */
153 204 100         for (j = 0; j < AES_BLOCKLEN; j++)
154             {
155 192           ctx->IV[j] = tmp2[j];
156             }
157 12           ct += AES_BLOCKLEN;
158 12           pt += AES_BLOCKLEN;
159             }
160 3           memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp));
161 3           memset_s(tmp2, sizeof(tmp2), 0x0, sizeof(tmp2));
162 3           }
163              
164             #endif /* USE_MATRIX_AES_CBC */
165              
166             /******************************************************************************/
167