xref: /aosp_15_r20/external/libsrtp2/crypto/hash/sha1.c (revision 90e502c7aef8d77d0622bb67d75435c6190cfc1a)
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