]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/modes/ccm128.c
1 /* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
50 #include <openssl/crypto.h>
51 #include "modes_lcl.h"
62 union { u8 c
[16]; size_t s
[16/sizeof(size_t)]; } nonce
, cmac
,
69 /* First you setup M and L parameters and pass the key schedule */
70 void CRYPTO_ccm128_init(CCM128_CONTEXT
*ctx
,
71 unsigned int M
,unsigned int L
,void *key
)
73 memset(ctx
->nonce
.c
,0,sizeof(ctx
->nonce
.c
));
74 ctx
->nonce
.c
[0] = ((u8
)(L
-1)&7) | (u8
)(((M
-2)/2)&7)<<3;
79 /* !!! Following interfaces are to be called *once* per packet !!! */
81 /* Then you setup per-message nonce and pass the length of the message */
82 int CRYPTO_ccm128_setiv(CCM128_CONTEXT
*ctx
,
83 const unsigned char *nonce
,size_t nlen
,size_t mlen
)
85 unsigned int L
= ctx
->nonce
.c
[0]&7; /* the L parameter */
87 if (nlen
<(14-L
)) return -1; /* nonce is too short */
89 if (sizeof(mlen
)==8 && L
>=3) {
90 ctx
->nonce
.c
[8] = (u8
)(mlen
>>(56%(sizeof(mlen
)*8)));
91 ctx
->nonce
.c
[9] = (u8
)(mlen
>>(48%(sizeof(mlen
)*8)));
92 ctx
->nonce
.c
[10] = (u8
)(mlen
>>(40%(sizeof(mlen
)*8)));
93 ctx
->nonce
.c
[11] = (u8
)(mlen
>>(32%(sizeof(mlen
)*8)));
96 *((size_t *)&ctx
->nonce
.s
[8]) = 0;
98 ctx
->nonce
.c
[12] = (u8
)(mlen
>>24);
99 ctx
->nonce
.c
[13] = (u8
)(mlen
>>16);
100 ctx
->nonce
.c
[14] = (u8
)(mlen
>>8);
101 ctx
->nonce
.c
[15] = (u8
)mlen
;
103 ctx
->nonce
.c
[0] &= ~0x40; /* clear Adata flag */
104 memcpy(&ctx
->nonce
.c
[1],nonce
,14-L
);
109 /* Then you pass additional authentication data, this is optional */
110 void CRYPTO_ccm128_aad(CCM128_CONTEXT
*ctx
,
111 const unsigned char *aad
,size_t alen
)
116 ctx
->nonce
.c
[0] |= 0x40; /* set Adata flag */
117 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,ctx
->key
),
120 if (alen
<(0x10000-0x100)) {
121 ctx
->cmac
.c
[0] ^= (u8
)(alen
>>8);
122 ctx
->cmac
.c
[1] ^= (u8
)alen
;
125 else if (sizeof(alen
)==8 && alen
>=(size_t)1<<32) {
126 ctx
->cmac
.c
[0] ^= 0xFF;
127 ctx
->cmac
.c
[1] ^= 0xFF;
128 ctx
->cmac
.c
[2] ^= (u8
)(alen
>>(56%(sizeof(alen
)*8)));
129 ctx
->cmac
.c
[3] ^= (u8
)(alen
>>(48%(sizeof(alen
)*8)));
130 ctx
->cmac
.c
[4] ^= (u8
)(alen
>>(40%(sizeof(alen
)*8)));
131 ctx
->cmac
.c
[5] ^= (u8
)(alen
>>(32%(sizeof(alen
)*8)));
132 ctx
->cmac
.c
[6] ^= (u8
)(alen
>>24);
133 ctx
->cmac
.c
[7] ^= (u8
)(alen
>>16);
134 ctx
->cmac
.c
[8] ^= (u8
)(alen
>>8);
135 ctx
->cmac
.c
[9] ^= (u8
)alen
;
139 ctx
->cmac
.c
[0] ^= 0xFF;
140 ctx
->cmac
.c
[1] ^= 0xFE;
141 ctx
->cmac
.c
[2] ^= (u8
)(alen
>>24);
142 ctx
->cmac
.c
[3] ^= (u8
)(alen
>>16);
143 ctx
->cmac
.c
[4] ^= (u8
)(alen
>>8);
144 ctx
->cmac
.c
[5] ^= (u8
)alen
;
149 for(;i
<16 && alen
;++i
,++aad
,--alen
)
150 ctx
->cmac
.c
[i
] ^= *aad
;
151 (*ctx
->block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
),
157 /* Finally you encrypt or decrypt the message */
159 static void ctr128_inc(unsigned char *counter
) {
172 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT
*ctx
,
173 const unsigned char *inp
, unsigned char *out
,
178 unsigned char flags
= ctx
->nonce
.c
[0];
181 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,ctx
->key
),
184 flags
&= 7; /* extract the L parameter */
185 for (n
=0,i
=15-flags
;i
<15;++i
) {
186 n
|= ctx
->nonce
.c
[i
]; ctx
->nonce
.c
[i
]=0;
189 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
192 if (n
!=len
) return -1; /* length mismatch */
194 ctx
->blocks
+= ((len
+15)>>3)|1;
195 if (ctx
->blocks
> (U64(1)<<61)) return -2; /* too much data */
198 #if defined(STRICT_ALIGNMENT)
199 memcpy (ctx
->inp
.c
,inp
,16);
200 for (i
=0; i
<16/sizeof(size_t); ++i
)
201 ctx
->cmac
.s
[i
] ^= ctx
->inp
.s
[i
];
203 for (i
=0; i
<16/sizeof(size_t); ++i
)
204 ctx
->cmac
.s
[i
] ^= ((size_t*)inp
)[i
];
206 (*ctx
->block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
);
207 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
208 ctr128_inc(ctx
->nonce
.c
);
209 #if defined(STRICT_ALIGNMENT)
210 for (i
=0; i
<16/sizeof(size_t); ++i
)
211 ctx
->inp
.s
[i
] ^= ctx
->scratch
.s
[i
];
212 memcpy(out
,ctx
->inp
.c
,16);
214 for (i
=0; i
<16/sizeof(size_t); ++i
)
215 ((size_t*)out
)[i
] = ctx
->scratch
.s
[i
]^((size_t*)inp
)[i
];
223 for (i
=0; i
<len
; ++i
) ctx
->cmac
.c
[i
] ^= inp
[i
];
224 (*ctx
->block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
);
225 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
226 for (i
=0; i
<len
; ++i
) out
[i
] = ctx
->scratch
.c
[i
]^inp
[i
];
229 for (i
=15-flags
;i
<16;++i
)
232 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
233 for (i
=0; i
<16/sizeof(size_t); ++i
)
234 ctx
->cmac
.s
[i
] ^= ctx
->scratch
.s
[i
];
239 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT
*ctx
,
240 const unsigned char *inp
, unsigned char *out
,
245 unsigned char flags
= ctx
->nonce
.c
[0];
248 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,ctx
->key
);
250 flags
&= 7; /* extract the L parameter */
251 for (n
=0,i
=15-flags
;i
<15;++i
) {
252 n
|= ctx
->nonce
.c
[i
]; ctx
->nonce
.c
[i
]=0;
255 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
258 if (n
!=len
) return -1;
261 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
262 ctr128_inc(ctx
->nonce
.c
);
263 #if defined(STRICT_ALIGNMENT)
264 memcpy (ctx
->inp
.c
,inp
,16);
265 for (i
=0; i
<16/sizeof(size_t); ++i
)
266 ctx
->cmac
.s
[i
] ^= (ctx
->scratch
.s
[i
] ^= ctx
->inp
.s
[i
]);
267 memcpy (out
,ctx
->scratch
,16);
269 for (i
=0; i
<16/sizeof(size_t); ++i
)
270 ctx
->cmac
.s
[i
] ^= ((size_t*)out
)[i
] = ctx
->scratch
.s
[i
]^((size_t*)inp
)[i
];
272 (*ctx
->block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
);
280 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
281 for (i
=0; i
<len
; ++len
)
282 ctx
->cmac
.c
[i
] ^= (out
[i
] = ctx
->scratch
.c
[i
]^inp
[i
]);
283 (*ctx
->block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
);
286 for (i
=15-flags
;i
<16;++i
)
289 (*ctx
->block
)(ctx
->nonce
.c
,ctx
->scratch
.c
,ctx
->key
);
290 for (i
=0; i
<16/sizeof(size_t); ++i
)
291 ctx
->cmac
.s
[i
] ^= ctx
->scratch
.s
[i
];
296 size_t CRYPTO_ccm128_tag(CCM128_CONTEXT
*ctx
,unsigned char *tag
,size_t len
)
297 { unsigned int M
= (ctx
->nonce
.c
[0]>>3)&7; /* the M parameter */
301 memcpy(tag
,ctx
->cmac
.c
,M
);