1*90e502c7SAndroid Build Coastguard Worker /*
2*90e502c7SAndroid Build Coastguard Worker * sha1.c
3*90e502c7SAndroid Build Coastguard Worker *
4*90e502c7SAndroid Build Coastguard Worker * an implementation of the Secure Hash Algorithm v.1 (SHA-1),
5*90e502c7SAndroid Build Coastguard Worker * specified in FIPS 180-1
6*90e502c7SAndroid Build Coastguard Worker *
7*90e502c7SAndroid Build Coastguard Worker * David A. McGrew
8*90e502c7SAndroid Build Coastguard Worker * Cisco Systems, Inc.
9*90e502c7SAndroid Build Coastguard Worker */
10*90e502c7SAndroid Build Coastguard Worker
11*90e502c7SAndroid Build Coastguard Worker /*
12*90e502c7SAndroid Build Coastguard Worker *
13*90e502c7SAndroid Build Coastguard Worker * Copyright (c) 2001-2017, Cisco Systems, Inc.
14*90e502c7SAndroid Build Coastguard Worker * All rights reserved.
15*90e502c7SAndroid Build Coastguard Worker *
16*90e502c7SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
17*90e502c7SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
18*90e502c7SAndroid Build Coastguard Worker * are met:
19*90e502c7SAndroid Build Coastguard Worker *
20*90e502c7SAndroid Build Coastguard Worker * Redistributions of source code must retain the above copyright
21*90e502c7SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
22*90e502c7SAndroid Build Coastguard Worker *
23*90e502c7SAndroid Build Coastguard Worker * Redistributions in binary form must reproduce the above
24*90e502c7SAndroid Build Coastguard Worker * copyright notice, this list of conditions and the following
25*90e502c7SAndroid Build Coastguard Worker * disclaimer in the documentation and/or other materials provided
26*90e502c7SAndroid Build Coastguard Worker * with the distribution.
27*90e502c7SAndroid Build Coastguard Worker *
28*90e502c7SAndroid Build Coastguard Worker * Neither the name of the Cisco Systems, Inc. nor the names of its
29*90e502c7SAndroid Build Coastguard Worker * contributors may be used to endorse or promote products derived
30*90e502c7SAndroid Build Coastguard Worker * from this software without specific prior written permission.
31*90e502c7SAndroid Build Coastguard Worker *
32*90e502c7SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*90e502c7SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*90e502c7SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35*90e502c7SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36*90e502c7SAndroid Build Coastguard Worker * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37*90e502c7SAndroid Build Coastguard Worker * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38*90e502c7SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39*90e502c7SAndroid Build Coastguard Worker * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40*90e502c7SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41*90e502c7SAndroid Build Coastguard Worker * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42*90e502c7SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43*90e502c7SAndroid Build Coastguard Worker * OF THE POSSIBILITY OF SUCH DAMAGE.
44*90e502c7SAndroid Build Coastguard Worker *
45*90e502c7SAndroid Build Coastguard Worker */
46*90e502c7SAndroid Build Coastguard Worker
47*90e502c7SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
48*90e502c7SAndroid Build Coastguard Worker #include <config.h>
49*90e502c7SAndroid Build Coastguard Worker #endif
50*90e502c7SAndroid Build Coastguard Worker
51*90e502c7SAndroid Build Coastguard Worker #include "sha1.h"
52*90e502c7SAndroid Build Coastguard Worker
53*90e502c7SAndroid Build Coastguard Worker srtp_debug_module_t srtp_mod_sha1 = {
54*90e502c7SAndroid Build Coastguard Worker 0, /* debugging is off by default */
55*90e502c7SAndroid Build Coastguard Worker "sha-1" /* printable module name */
56*90e502c7SAndroid Build Coastguard Worker };
57*90e502c7SAndroid Build Coastguard Worker
58*90e502c7SAndroid Build Coastguard Worker /* SN == Rotate left N bits */
59*90e502c7SAndroid Build Coastguard Worker #define S1(X) ((X << 1) | (X >> 31))
60*90e502c7SAndroid Build Coastguard Worker #define S5(X) ((X << 5) | (X >> 27))
61*90e502c7SAndroid Build Coastguard Worker #define S30(X) ((X << 30) | (X >> 2))
62*90e502c7SAndroid Build Coastguard Worker
63*90e502c7SAndroid Build Coastguard Worker #define f0(B, C, D) ((B & C) | (~B & D))
64*90e502c7SAndroid Build Coastguard Worker #define f1(B, C, D) (B ^ C ^ D)
65*90e502c7SAndroid Build Coastguard Worker #define f2(B, C, D) ((B & C) | (B & D) | (C & D))
66*90e502c7SAndroid Build Coastguard Worker #define f3(B, C, D) (B ^ C ^ D)
67*90e502c7SAndroid Build Coastguard Worker
68*90e502c7SAndroid Build Coastguard Worker /*
69*90e502c7SAndroid Build Coastguard Worker * nota bene: the variable K0 appears in the curses library, so we
70*90e502c7SAndroid Build Coastguard Worker * give longer names to these variables to avoid spurious warnings
71*90e502c7SAndroid Build Coastguard Worker * on systems that uses curses
72*90e502c7SAndroid Build Coastguard Worker */
73*90e502c7SAndroid Build Coastguard Worker
74*90e502c7SAndroid Build Coastguard Worker uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */
75*90e502c7SAndroid Build Coastguard Worker uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
76*90e502c7SAndroid Build Coastguard Worker uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
77*90e502c7SAndroid Build Coastguard Worker uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
78*90e502c7SAndroid Build Coastguard Worker
srtp_sha1(const uint8_t * msg,int octets_in_msg,uint32_t hash_value[5])79*90e502c7SAndroid Build Coastguard Worker void srtp_sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
80*90e502c7SAndroid Build Coastguard Worker {
81*90e502c7SAndroid Build Coastguard Worker srtp_sha1_ctx_t ctx;
82*90e502c7SAndroid Build Coastguard Worker
83*90e502c7SAndroid Build Coastguard Worker srtp_sha1_init(&ctx);
84*90e502c7SAndroid Build Coastguard Worker srtp_sha1_update(&ctx, msg, octets_in_msg);
85*90e502c7SAndroid Build Coastguard Worker srtp_sha1_final(&ctx, hash_value);
86*90e502c7SAndroid Build Coastguard Worker }
87*90e502c7SAndroid Build Coastguard Worker
88*90e502c7SAndroid Build Coastguard Worker /*
89*90e502c7SAndroid Build Coastguard Worker * srtp_sha1_core(M, H) computes the core compression function, where M is
90*90e502c7SAndroid Build Coastguard Worker * the next part of the message (in network byte order) and H is the
91*90e502c7SAndroid Build Coastguard Worker * intermediate state { H0, H1, ...} (in host byte order)
92*90e502c7SAndroid Build Coastguard Worker *
93*90e502c7SAndroid Build Coastguard Worker * this function does not do any of the padding required in the
94*90e502c7SAndroid Build Coastguard Worker * complete SHA1 function
95*90e502c7SAndroid Build Coastguard Worker *
96*90e502c7SAndroid Build Coastguard Worker * this function is used in the SEAL 3.0 key setup routines
97*90e502c7SAndroid Build Coastguard Worker * (crypto/cipher/seal.c)
98*90e502c7SAndroid Build Coastguard Worker */
99*90e502c7SAndroid Build Coastguard Worker
srtp_sha1_core(const uint32_t M[16],uint32_t hash_value[5])100*90e502c7SAndroid Build Coastguard Worker void srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5])
101*90e502c7SAndroid Build Coastguard Worker {
102*90e502c7SAndroid Build Coastguard Worker uint32_t H0;
103*90e502c7SAndroid Build Coastguard Worker uint32_t H1;
104*90e502c7SAndroid Build Coastguard Worker uint32_t H2;
105*90e502c7SAndroid Build Coastguard Worker uint32_t H3;
106*90e502c7SAndroid Build Coastguard Worker uint32_t H4;
107*90e502c7SAndroid Build Coastguard Worker uint32_t W[80];
108*90e502c7SAndroid Build Coastguard Worker uint32_t A, B, C, D, E, TEMP;
109*90e502c7SAndroid Build Coastguard Worker int t;
110*90e502c7SAndroid Build Coastguard Worker
111*90e502c7SAndroid Build Coastguard Worker /* copy hash_value into H0, H1, H2, H3, H4 */
112*90e502c7SAndroid Build Coastguard Worker H0 = hash_value[0];
113*90e502c7SAndroid Build Coastguard Worker H1 = hash_value[1];
114*90e502c7SAndroid Build Coastguard Worker H2 = hash_value[2];
115*90e502c7SAndroid Build Coastguard Worker H3 = hash_value[3];
116*90e502c7SAndroid Build Coastguard Worker H4 = hash_value[4];
117*90e502c7SAndroid Build Coastguard Worker
118*90e502c7SAndroid Build Coastguard Worker /* copy/xor message into array */
119*90e502c7SAndroid Build Coastguard Worker
120*90e502c7SAndroid Build Coastguard Worker W[0] = be32_to_cpu(M[0]);
121*90e502c7SAndroid Build Coastguard Worker W[1] = be32_to_cpu(M[1]);
122*90e502c7SAndroid Build Coastguard Worker W[2] = be32_to_cpu(M[2]);
123*90e502c7SAndroid Build Coastguard Worker W[3] = be32_to_cpu(M[3]);
124*90e502c7SAndroid Build Coastguard Worker W[4] = be32_to_cpu(M[4]);
125*90e502c7SAndroid Build Coastguard Worker W[5] = be32_to_cpu(M[5]);
126*90e502c7SAndroid Build Coastguard Worker W[6] = be32_to_cpu(M[6]);
127*90e502c7SAndroid Build Coastguard Worker W[7] = be32_to_cpu(M[7]);
128*90e502c7SAndroid Build Coastguard Worker W[8] = be32_to_cpu(M[8]);
129*90e502c7SAndroid Build Coastguard Worker W[9] = be32_to_cpu(M[9]);
130*90e502c7SAndroid Build Coastguard Worker W[10] = be32_to_cpu(M[10]);
131*90e502c7SAndroid Build Coastguard Worker W[11] = be32_to_cpu(M[11]);
132*90e502c7SAndroid Build Coastguard Worker W[12] = be32_to_cpu(M[12]);
133*90e502c7SAndroid Build Coastguard Worker W[13] = be32_to_cpu(M[13]);
134*90e502c7SAndroid Build Coastguard Worker W[14] = be32_to_cpu(M[14]);
135*90e502c7SAndroid Build Coastguard Worker W[15] = be32_to_cpu(M[15]);
136*90e502c7SAndroid Build Coastguard Worker TEMP = W[13] ^ W[8] ^ W[2] ^ W[0];
137*90e502c7SAndroid Build Coastguard Worker W[16] = S1(TEMP);
138*90e502c7SAndroid Build Coastguard Worker TEMP = W[14] ^ W[9] ^ W[3] ^ W[1];
139*90e502c7SAndroid Build Coastguard Worker W[17] = S1(TEMP);
140*90e502c7SAndroid Build Coastguard Worker TEMP = W[15] ^ W[10] ^ W[4] ^ W[2];
141*90e502c7SAndroid Build Coastguard Worker W[18] = S1(TEMP);
142*90e502c7SAndroid Build Coastguard Worker TEMP = W[16] ^ W[11] ^ W[5] ^ W[3];
143*90e502c7SAndroid Build Coastguard Worker W[19] = S1(TEMP);
144*90e502c7SAndroid Build Coastguard Worker TEMP = W[17] ^ W[12] ^ W[6] ^ W[4];
145*90e502c7SAndroid Build Coastguard Worker W[20] = S1(TEMP);
146*90e502c7SAndroid Build Coastguard Worker TEMP = W[18] ^ W[13] ^ W[7] ^ W[5];
147*90e502c7SAndroid Build Coastguard Worker W[21] = S1(TEMP);
148*90e502c7SAndroid Build Coastguard Worker TEMP = W[19] ^ W[14] ^ W[8] ^ W[6];
149*90e502c7SAndroid Build Coastguard Worker W[22] = S1(TEMP);
150*90e502c7SAndroid Build Coastguard Worker TEMP = W[20] ^ W[15] ^ W[9] ^ W[7];
151*90e502c7SAndroid Build Coastguard Worker W[23] = S1(TEMP);
152*90e502c7SAndroid Build Coastguard Worker TEMP = W[21] ^ W[16] ^ W[10] ^ W[8];
153*90e502c7SAndroid Build Coastguard Worker W[24] = S1(TEMP);
154*90e502c7SAndroid Build Coastguard Worker TEMP = W[22] ^ W[17] ^ W[11] ^ W[9];
155*90e502c7SAndroid Build Coastguard Worker W[25] = S1(TEMP);
156*90e502c7SAndroid Build Coastguard Worker TEMP = W[23] ^ W[18] ^ W[12] ^ W[10];
157*90e502c7SAndroid Build Coastguard Worker W[26] = S1(TEMP);
158*90e502c7SAndroid Build Coastguard Worker TEMP = W[24] ^ W[19] ^ W[13] ^ W[11];
159*90e502c7SAndroid Build Coastguard Worker W[27] = S1(TEMP);
160*90e502c7SAndroid Build Coastguard Worker TEMP = W[25] ^ W[20] ^ W[14] ^ W[12];
161*90e502c7SAndroid Build Coastguard Worker W[28] = S1(TEMP);
162*90e502c7SAndroid Build Coastguard Worker TEMP = W[26] ^ W[21] ^ W[15] ^ W[13];
163*90e502c7SAndroid Build Coastguard Worker W[29] = S1(TEMP);
164*90e502c7SAndroid Build Coastguard Worker TEMP = W[27] ^ W[22] ^ W[16] ^ W[14];
165*90e502c7SAndroid Build Coastguard Worker W[30] = S1(TEMP);
166*90e502c7SAndroid Build Coastguard Worker TEMP = W[28] ^ W[23] ^ W[17] ^ W[15];
167*90e502c7SAndroid Build Coastguard Worker W[31] = S1(TEMP);
168*90e502c7SAndroid Build Coastguard Worker
169*90e502c7SAndroid Build Coastguard Worker /* process the remainder of the array */
170*90e502c7SAndroid Build Coastguard Worker for (t = 32; t < 80; t++) {
171*90e502c7SAndroid Build Coastguard Worker TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
172*90e502c7SAndroid Build Coastguard Worker W[t] = S1(TEMP);
173*90e502c7SAndroid Build Coastguard Worker }
174*90e502c7SAndroid Build Coastguard Worker
175*90e502c7SAndroid Build Coastguard Worker A = H0;
176*90e502c7SAndroid Build Coastguard Worker B = H1;
177*90e502c7SAndroid Build Coastguard Worker C = H2;
178*90e502c7SAndroid Build Coastguard Worker D = H3;
179*90e502c7SAndroid Build Coastguard Worker E = H4;
180*90e502c7SAndroid Build Coastguard Worker
181*90e502c7SAndroid Build Coastguard Worker for (t = 0; t < 20; t++) {
182*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
183*90e502c7SAndroid Build Coastguard Worker E = D;
184*90e502c7SAndroid Build Coastguard Worker D = C;
185*90e502c7SAndroid Build Coastguard Worker C = S30(B);
186*90e502c7SAndroid Build Coastguard Worker B = A;
187*90e502c7SAndroid Build Coastguard Worker A = TEMP;
188*90e502c7SAndroid Build Coastguard Worker }
189*90e502c7SAndroid Build Coastguard Worker for (; t < 40; t++) {
190*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
191*90e502c7SAndroid Build Coastguard Worker E = D;
192*90e502c7SAndroid Build Coastguard Worker D = C;
193*90e502c7SAndroid Build Coastguard Worker C = S30(B);
194*90e502c7SAndroid Build Coastguard Worker B = A;
195*90e502c7SAndroid Build Coastguard Worker A = TEMP;
196*90e502c7SAndroid Build Coastguard Worker }
197*90e502c7SAndroid Build Coastguard Worker for (; t < 60; t++) {
198*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
199*90e502c7SAndroid Build Coastguard Worker E = D;
200*90e502c7SAndroid Build Coastguard Worker D = C;
201*90e502c7SAndroid Build Coastguard Worker C = S30(B);
202*90e502c7SAndroid Build Coastguard Worker B = A;
203*90e502c7SAndroid Build Coastguard Worker A = TEMP;
204*90e502c7SAndroid Build Coastguard Worker }
205*90e502c7SAndroid Build Coastguard Worker for (; t < 80; t++) {
206*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
207*90e502c7SAndroid Build Coastguard Worker E = D;
208*90e502c7SAndroid Build Coastguard Worker D = C;
209*90e502c7SAndroid Build Coastguard Worker C = S30(B);
210*90e502c7SAndroid Build Coastguard Worker B = A;
211*90e502c7SAndroid Build Coastguard Worker A = TEMP;
212*90e502c7SAndroid Build Coastguard Worker }
213*90e502c7SAndroid Build Coastguard Worker
214*90e502c7SAndroid Build Coastguard Worker hash_value[0] = H0 + A;
215*90e502c7SAndroid Build Coastguard Worker hash_value[1] = H1 + B;
216*90e502c7SAndroid Build Coastguard Worker hash_value[2] = H2 + C;
217*90e502c7SAndroid Build Coastguard Worker hash_value[3] = H3 + D;
218*90e502c7SAndroid Build Coastguard Worker hash_value[4] = H4 + E;
219*90e502c7SAndroid Build Coastguard Worker
220*90e502c7SAndroid Build Coastguard Worker return;
221*90e502c7SAndroid Build Coastguard Worker }
222*90e502c7SAndroid Build Coastguard Worker
srtp_sha1_init(srtp_sha1_ctx_t * ctx)223*90e502c7SAndroid Build Coastguard Worker void srtp_sha1_init(srtp_sha1_ctx_t *ctx)
224*90e502c7SAndroid Build Coastguard Worker {
225*90e502c7SAndroid Build Coastguard Worker /* initialize state vector */
226*90e502c7SAndroid Build Coastguard Worker ctx->H[0] = 0x67452301;
227*90e502c7SAndroid Build Coastguard Worker ctx->H[1] = 0xefcdab89;
228*90e502c7SAndroid Build Coastguard Worker ctx->H[2] = 0x98badcfe;
229*90e502c7SAndroid Build Coastguard Worker ctx->H[3] = 0x10325476;
230*90e502c7SAndroid Build Coastguard Worker ctx->H[4] = 0xc3d2e1f0;
231*90e502c7SAndroid Build Coastguard Worker
232*90e502c7SAndroid Build Coastguard Worker /* indicate that message buffer is empty */
233*90e502c7SAndroid Build Coastguard Worker ctx->octets_in_buffer = 0;
234*90e502c7SAndroid Build Coastguard Worker
235*90e502c7SAndroid Build Coastguard Worker /* reset message bit-count to zero */
236*90e502c7SAndroid Build Coastguard Worker ctx->num_bits_in_msg = 0;
237*90e502c7SAndroid Build Coastguard Worker }
238*90e502c7SAndroid Build Coastguard Worker
srtp_sha1_update(srtp_sha1_ctx_t * ctx,const uint8_t * msg,int octets_in_msg)239*90e502c7SAndroid Build Coastguard Worker void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
240*90e502c7SAndroid Build Coastguard Worker const uint8_t *msg,
241*90e502c7SAndroid Build Coastguard Worker int octets_in_msg)
242*90e502c7SAndroid Build Coastguard Worker {
243*90e502c7SAndroid Build Coastguard Worker int i;
244*90e502c7SAndroid Build Coastguard Worker uint8_t *buf = (uint8_t *)ctx->M;
245*90e502c7SAndroid Build Coastguard Worker
246*90e502c7SAndroid Build Coastguard Worker /* update message bit-count */
247*90e502c7SAndroid Build Coastguard Worker ctx->num_bits_in_msg += octets_in_msg * 8;
248*90e502c7SAndroid Build Coastguard Worker
249*90e502c7SAndroid Build Coastguard Worker /* loop over 16-word blocks of M */
250*90e502c7SAndroid Build Coastguard Worker while (octets_in_msg > 0) {
251*90e502c7SAndroid Build Coastguard Worker if (octets_in_msg + ctx->octets_in_buffer >= 64) {
252*90e502c7SAndroid Build Coastguard Worker /*
253*90e502c7SAndroid Build Coastguard Worker * copy words of M into msg buffer until that buffer is full,
254*90e502c7SAndroid Build Coastguard Worker * converting them into host byte order as needed
255*90e502c7SAndroid Build Coastguard Worker */
256*90e502c7SAndroid Build Coastguard Worker octets_in_msg -= (64 - ctx->octets_in_buffer);
257*90e502c7SAndroid Build Coastguard Worker for (i = ctx->octets_in_buffer; i < 64; i++) {
258*90e502c7SAndroid Build Coastguard Worker buf[i] = *msg++;
259*90e502c7SAndroid Build Coastguard Worker }
260*90e502c7SAndroid Build Coastguard Worker ctx->octets_in_buffer = 0;
261*90e502c7SAndroid Build Coastguard Worker
262*90e502c7SAndroid Build Coastguard Worker /* process a whole block */
263*90e502c7SAndroid Build Coastguard Worker
264*90e502c7SAndroid Build Coastguard Worker debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()",
265*90e502c7SAndroid Build Coastguard Worker NULL);
266*90e502c7SAndroid Build Coastguard Worker
267*90e502c7SAndroid Build Coastguard Worker srtp_sha1_core(ctx->M, ctx->H);
268*90e502c7SAndroid Build Coastguard Worker
269*90e502c7SAndroid Build Coastguard Worker } else {
270*90e502c7SAndroid Build Coastguard Worker debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()",
271*90e502c7SAndroid Build Coastguard Worker NULL);
272*90e502c7SAndroid Build Coastguard Worker
273*90e502c7SAndroid Build Coastguard Worker for (i = ctx->octets_in_buffer;
274*90e502c7SAndroid Build Coastguard Worker i < (ctx->octets_in_buffer + octets_in_msg); i++) {
275*90e502c7SAndroid Build Coastguard Worker buf[i] = *msg++;
276*90e502c7SAndroid Build Coastguard Worker }
277*90e502c7SAndroid Build Coastguard Worker ctx->octets_in_buffer += octets_in_msg;
278*90e502c7SAndroid Build Coastguard Worker octets_in_msg = 0;
279*90e502c7SAndroid Build Coastguard Worker }
280*90e502c7SAndroid Build Coastguard Worker }
281*90e502c7SAndroid Build Coastguard Worker }
282*90e502c7SAndroid Build Coastguard Worker
283*90e502c7SAndroid Build Coastguard Worker /*
284*90e502c7SAndroid Build Coastguard Worker * srtp_sha1_final(ctx, output) computes the result for ctx and copies it
285*90e502c7SAndroid Build Coastguard Worker * into the twenty octets located at *output
286*90e502c7SAndroid Build Coastguard Worker */
287*90e502c7SAndroid Build Coastguard Worker
srtp_sha1_final(srtp_sha1_ctx_t * ctx,uint32_t * output)288*90e502c7SAndroid Build Coastguard Worker void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
289*90e502c7SAndroid Build Coastguard Worker {
290*90e502c7SAndroid Build Coastguard Worker uint32_t A, B, C, D, E, TEMP;
291*90e502c7SAndroid Build Coastguard Worker uint32_t W[80];
292*90e502c7SAndroid Build Coastguard Worker int i, t;
293*90e502c7SAndroid Build Coastguard Worker
294*90e502c7SAndroid Build Coastguard Worker /*
295*90e502c7SAndroid Build Coastguard Worker * process the remaining octets_in_buffer, padding and terminating as
296*90e502c7SAndroid Build Coastguard Worker * necessary
297*90e502c7SAndroid Build Coastguard Worker */
298*90e502c7SAndroid Build Coastguard Worker {
299*90e502c7SAndroid Build Coastguard Worker int tail = ctx->octets_in_buffer % 4;
300*90e502c7SAndroid Build Coastguard Worker
301*90e502c7SAndroid Build Coastguard Worker /* copy/xor message into array */
302*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < (ctx->octets_in_buffer + 3) / 4; i++) {
303*90e502c7SAndroid Build Coastguard Worker W[i] = be32_to_cpu(ctx->M[i]);
304*90e502c7SAndroid Build Coastguard Worker }
305*90e502c7SAndroid Build Coastguard Worker
306*90e502c7SAndroid Build Coastguard Worker /* set the high bit of the octet immediately following the message */
307*90e502c7SAndroid Build Coastguard Worker switch (tail) {
308*90e502c7SAndroid Build Coastguard Worker case (3):
309*90e502c7SAndroid Build Coastguard Worker W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffffff00) | 0x80;
310*90e502c7SAndroid Build Coastguard Worker W[i] = 0x0;
311*90e502c7SAndroid Build Coastguard Worker break;
312*90e502c7SAndroid Build Coastguard Worker case (2):
313*90e502c7SAndroid Build Coastguard Worker W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffff0000) | 0x8000;
314*90e502c7SAndroid Build Coastguard Worker W[i] = 0x0;
315*90e502c7SAndroid Build Coastguard Worker break;
316*90e502c7SAndroid Build Coastguard Worker case (1):
317*90e502c7SAndroid Build Coastguard Worker W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xff000000) | 0x800000;
318*90e502c7SAndroid Build Coastguard Worker W[i] = 0x0;
319*90e502c7SAndroid Build Coastguard Worker break;
320*90e502c7SAndroid Build Coastguard Worker case (0):
321*90e502c7SAndroid Build Coastguard Worker W[i] = 0x80000000;
322*90e502c7SAndroid Build Coastguard Worker break;
323*90e502c7SAndroid Build Coastguard Worker }
324*90e502c7SAndroid Build Coastguard Worker
325*90e502c7SAndroid Build Coastguard Worker /* zeroize remaining words */
326*90e502c7SAndroid Build Coastguard Worker for (i++; i < 15; i++) {
327*90e502c7SAndroid Build Coastguard Worker W[i] = 0x0;
328*90e502c7SAndroid Build Coastguard Worker }
329*90e502c7SAndroid Build Coastguard Worker
330*90e502c7SAndroid Build Coastguard Worker /*
331*90e502c7SAndroid Build Coastguard Worker * if there is room at the end of the word array, then set the
332*90e502c7SAndroid Build Coastguard Worker * last word to the bit-length of the message; otherwise, set that
333*90e502c7SAndroid Build Coastguard Worker * word to zero and then we need to do one more run of the
334*90e502c7SAndroid Build Coastguard Worker * compression algo.
335*90e502c7SAndroid Build Coastguard Worker */
336*90e502c7SAndroid Build Coastguard Worker if (ctx->octets_in_buffer < 56) {
337*90e502c7SAndroid Build Coastguard Worker W[15] = ctx->num_bits_in_msg;
338*90e502c7SAndroid Build Coastguard Worker } else if (ctx->octets_in_buffer < 60) {
339*90e502c7SAndroid Build Coastguard Worker W[15] = 0x0;
340*90e502c7SAndroid Build Coastguard Worker }
341*90e502c7SAndroid Build Coastguard Worker
342*90e502c7SAndroid Build Coastguard Worker /* process the word array */
343*90e502c7SAndroid Build Coastguard Worker for (t = 16; t < 80; t++) {
344*90e502c7SAndroid Build Coastguard Worker TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
345*90e502c7SAndroid Build Coastguard Worker W[t] = S1(TEMP);
346*90e502c7SAndroid Build Coastguard Worker }
347*90e502c7SAndroid Build Coastguard Worker
348*90e502c7SAndroid Build Coastguard Worker A = ctx->H[0];
349*90e502c7SAndroid Build Coastguard Worker B = ctx->H[1];
350*90e502c7SAndroid Build Coastguard Worker C = ctx->H[2];
351*90e502c7SAndroid Build Coastguard Worker D = ctx->H[3];
352*90e502c7SAndroid Build Coastguard Worker E = ctx->H[4];
353*90e502c7SAndroid Build Coastguard Worker
354*90e502c7SAndroid Build Coastguard Worker for (t = 0; t < 20; t++) {
355*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
356*90e502c7SAndroid Build Coastguard Worker E = D;
357*90e502c7SAndroid Build Coastguard Worker D = C;
358*90e502c7SAndroid Build Coastguard Worker C = S30(B);
359*90e502c7SAndroid Build Coastguard Worker B = A;
360*90e502c7SAndroid Build Coastguard Worker A = TEMP;
361*90e502c7SAndroid Build Coastguard Worker }
362*90e502c7SAndroid Build Coastguard Worker for (; t < 40; t++) {
363*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
364*90e502c7SAndroid Build Coastguard Worker E = D;
365*90e502c7SAndroid Build Coastguard Worker D = C;
366*90e502c7SAndroid Build Coastguard Worker C = S30(B);
367*90e502c7SAndroid Build Coastguard Worker B = A;
368*90e502c7SAndroid Build Coastguard Worker A = TEMP;
369*90e502c7SAndroid Build Coastguard Worker }
370*90e502c7SAndroid Build Coastguard Worker for (; t < 60; t++) {
371*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
372*90e502c7SAndroid Build Coastguard Worker E = D;
373*90e502c7SAndroid Build Coastguard Worker D = C;
374*90e502c7SAndroid Build Coastguard Worker C = S30(B);
375*90e502c7SAndroid Build Coastguard Worker B = A;
376*90e502c7SAndroid Build Coastguard Worker A = TEMP;
377*90e502c7SAndroid Build Coastguard Worker }
378*90e502c7SAndroid Build Coastguard Worker for (; t < 80; t++) {
379*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
380*90e502c7SAndroid Build Coastguard Worker E = D;
381*90e502c7SAndroid Build Coastguard Worker D = C;
382*90e502c7SAndroid Build Coastguard Worker C = S30(B);
383*90e502c7SAndroid Build Coastguard Worker B = A;
384*90e502c7SAndroid Build Coastguard Worker A = TEMP;
385*90e502c7SAndroid Build Coastguard Worker }
386*90e502c7SAndroid Build Coastguard Worker
387*90e502c7SAndroid Build Coastguard Worker ctx->H[0] += A;
388*90e502c7SAndroid Build Coastguard Worker ctx->H[1] += B;
389*90e502c7SAndroid Build Coastguard Worker ctx->H[2] += C;
390*90e502c7SAndroid Build Coastguard Worker ctx->H[3] += D;
391*90e502c7SAndroid Build Coastguard Worker ctx->H[4] += E;
392*90e502c7SAndroid Build Coastguard Worker }
393*90e502c7SAndroid Build Coastguard Worker
394*90e502c7SAndroid Build Coastguard Worker debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
395*90e502c7SAndroid Build Coastguard Worker
396*90e502c7SAndroid Build Coastguard Worker if (ctx->octets_in_buffer >= 56) {
397*90e502c7SAndroid Build Coastguard Worker debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again",
398*90e502c7SAndroid Build Coastguard Worker NULL);
399*90e502c7SAndroid Build Coastguard Worker
400*90e502c7SAndroid Build Coastguard Worker /* we need to do one final run of the compression algo */
401*90e502c7SAndroid Build Coastguard Worker
402*90e502c7SAndroid Build Coastguard Worker /*
403*90e502c7SAndroid Build Coastguard Worker * set initial part of word array to zeros, and set the
404*90e502c7SAndroid Build Coastguard Worker * final part to the number of bits in the message
405*90e502c7SAndroid Build Coastguard Worker */
406*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 15; i++) {
407*90e502c7SAndroid Build Coastguard Worker W[i] = 0x0;
408*90e502c7SAndroid Build Coastguard Worker }
409*90e502c7SAndroid Build Coastguard Worker W[15] = ctx->num_bits_in_msg;
410*90e502c7SAndroid Build Coastguard Worker
411*90e502c7SAndroid Build Coastguard Worker /* process the word array */
412*90e502c7SAndroid Build Coastguard Worker for (t = 16; t < 80; t++) {
413*90e502c7SAndroid Build Coastguard Worker TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
414*90e502c7SAndroid Build Coastguard Worker W[t] = S1(TEMP);
415*90e502c7SAndroid Build Coastguard Worker }
416*90e502c7SAndroid Build Coastguard Worker
417*90e502c7SAndroid Build Coastguard Worker A = ctx->H[0];
418*90e502c7SAndroid Build Coastguard Worker B = ctx->H[1];
419*90e502c7SAndroid Build Coastguard Worker C = ctx->H[2];
420*90e502c7SAndroid Build Coastguard Worker D = ctx->H[3];
421*90e502c7SAndroid Build Coastguard Worker E = ctx->H[4];
422*90e502c7SAndroid Build Coastguard Worker
423*90e502c7SAndroid Build Coastguard Worker for (t = 0; t < 20; t++) {
424*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
425*90e502c7SAndroid Build Coastguard Worker E = D;
426*90e502c7SAndroid Build Coastguard Worker D = C;
427*90e502c7SAndroid Build Coastguard Worker C = S30(B);
428*90e502c7SAndroid Build Coastguard Worker B = A;
429*90e502c7SAndroid Build Coastguard Worker A = TEMP;
430*90e502c7SAndroid Build Coastguard Worker }
431*90e502c7SAndroid Build Coastguard Worker for (; t < 40; t++) {
432*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
433*90e502c7SAndroid Build Coastguard Worker E = D;
434*90e502c7SAndroid Build Coastguard Worker D = C;
435*90e502c7SAndroid Build Coastguard Worker C = S30(B);
436*90e502c7SAndroid Build Coastguard Worker B = A;
437*90e502c7SAndroid Build Coastguard Worker A = TEMP;
438*90e502c7SAndroid Build Coastguard Worker }
439*90e502c7SAndroid Build Coastguard Worker for (; t < 60; t++) {
440*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
441*90e502c7SAndroid Build Coastguard Worker E = D;
442*90e502c7SAndroid Build Coastguard Worker D = C;
443*90e502c7SAndroid Build Coastguard Worker C = S30(B);
444*90e502c7SAndroid Build Coastguard Worker B = A;
445*90e502c7SAndroid Build Coastguard Worker A = TEMP;
446*90e502c7SAndroid Build Coastguard Worker }
447*90e502c7SAndroid Build Coastguard Worker for (; t < 80; t++) {
448*90e502c7SAndroid Build Coastguard Worker TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
449*90e502c7SAndroid Build Coastguard Worker E = D;
450*90e502c7SAndroid Build Coastguard Worker D = C;
451*90e502c7SAndroid Build Coastguard Worker C = S30(B);
452*90e502c7SAndroid Build Coastguard Worker B = A;
453*90e502c7SAndroid Build Coastguard Worker A = TEMP;
454*90e502c7SAndroid Build Coastguard Worker }
455*90e502c7SAndroid Build Coastguard Worker
456*90e502c7SAndroid Build Coastguard Worker ctx->H[0] += A;
457*90e502c7SAndroid Build Coastguard Worker ctx->H[1] += B;
458*90e502c7SAndroid Build Coastguard Worker ctx->H[2] += C;
459*90e502c7SAndroid Build Coastguard Worker ctx->H[3] += D;
460*90e502c7SAndroid Build Coastguard Worker ctx->H[4] += E;
461*90e502c7SAndroid Build Coastguard Worker }
462*90e502c7SAndroid Build Coastguard Worker
463*90e502c7SAndroid Build Coastguard Worker /* copy result into output buffer */
464*90e502c7SAndroid Build Coastguard Worker output[0] = be32_to_cpu(ctx->H[0]);
465*90e502c7SAndroid Build Coastguard Worker output[1] = be32_to_cpu(ctx->H[1]);
466*90e502c7SAndroid Build Coastguard Worker output[2] = be32_to_cpu(ctx->H[2]);
467*90e502c7SAndroid Build Coastguard Worker output[3] = be32_to_cpu(ctx->H[3]);
468*90e502c7SAndroid Build Coastguard Worker output[4] = be32_to_cpu(ctx->H[4]);
469*90e502c7SAndroid Build Coastguard Worker
470*90e502c7SAndroid Build Coastguard Worker /* indicate that message buffer in context is empty */
471*90e502c7SAndroid Build Coastguard Worker ctx->octets_in_buffer = 0;
472*90e502c7SAndroid Build Coastguard Worker
473*90e502c7SAndroid Build Coastguard Worker return;
474*90e502c7SAndroid Build Coastguard Worker }
475