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