/* * sha1.c * * an implementation of the Secure Hash Algorithm v.1 (SHA-1), * specified in FIPS 180-1 * * David A. McGrew * Cisco Systems, Inc.
*/
/* * * Copyright (c) 2001-2017, Cisco Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. *
*/
#ifdef HAVE_CONFIG_H #include <config.h> #endif
#include"sha1.h"
srtp_debug_module_t srtp_mod_sha1 = {
0, /* debugging is off by default */ "sha-1"/* printable module name */
};
/* * nota bene: the variable K0 appears in the curses library, so we * give longer names to these variables to avoid spurious warnings * on systems that uses curses
*/
uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */
uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
/* * srtp_sha1_core(M, H) computes the core compression function, where M is * the next part of the message (in network byte order) and H is the * intermediate state { H0, H1, ...} (in host byte order) * * this function does not do any of the padding required in the * complete SHA1 function * * this function is used in the SEAL 3.0 key setup routines * (crypto/cipher/seal.c)
*/
void srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5])
{
uint32_t H0;
uint32_t H1;
uint32_t H2;
uint32_t H3;
uint32_t H4;
uint32_t W[80];
uint32_t A, B, C, D, E, TEMP; int t;
/* process the remainder of the array */ for (t = 32; t < 80; t++) {
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP);
}
A = H0;
B = H1;
C = H2;
D = H3;
E = H4;
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
/* loop over 16-word blocks of M */ while (octets_in_msg > 0) { if (octets_in_msg + ctx->octets_in_buffer >= 64) { /* * copy words of M into msg buffer until that buffer is full, * converting them into host byte order as needed
*/
octets_in_msg -= (64 - ctx->octets_in_buffer); for (i = ctx->octets_in_buffer; i < 64; i++) {
buf[i] = *msg++;
}
ctx->octets_in_buffer = 0;
} else {
debug_print0(srtp_mod_sha1, "(update) not running srtp_sha1_core()");
for (i = ctx->octets_in_buffer;
i < (ctx->octets_in_buffer + octets_in_msg); i++) {
buf[i] = *msg++;
}
ctx->octets_in_buffer += octets_in_msg;
octets_in_msg = 0;
}
}
}
/* * srtp_sha1_final(ctx, output) computes the result for ctx and copies it * into the twenty octets located at *output
*/
void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t output[5])
{
uint32_t A, B, C, D, E, TEMP;
uint32_t W[80]; int i, t;
/* * process the remaining octets_in_buffer, padding and terminating as * necessary
*/
{ int tail = ctx->octets_in_buffer % 4;
/* copy/xor message into array */ for (i = 0; i < (ctx->octets_in_buffer + 3) / 4; i++) {
W[i] = be32_to_cpu(ctx->M[i]);
}
/* set the high bit of the octet immediately following the message */ switch (tail) { case (3):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffffff00) | 0x80;
W[i] = 0x0; break; case (2):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffff0000) | 0x8000;
W[i] = 0x0; break; case (1):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xff000000) | 0x800000;
W[i] = 0x0; break; case (0):
W[i] = 0x80000000; break;
}
/* zeroize remaining words */ for (i++; i < 15; i++) {
W[i] = 0x0;
}
/* * if there is room at the end of the word array, then set the * last word to the bit-length of the message; otherwise, set that * word to zero and then we need to do one more run of the * compression algo.
*/ if (ctx->octets_in_buffer < 56) {
W[15] = ctx->num_bits_in_msg;
} elseif (ctx->octets_in_buffer < 60) {
W[15] = 0x0;
}
/* process the word array */ for (t = 16; t < 80; t++) {
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP);
}
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
if (ctx->octets_in_buffer >= 56) {
debug_print0(srtp_mod_sha1, "(final) running srtp_sha1_core() again");
/* we need to do one final run of the compression algo */
/* * set initial part of word array to zeros, and set the * final part to the number of bits in the message
*/ for (i = 0; i < 15; i++) {
W[i] = 0x0;
}
W[15] = ctx->num_bits_in_msg;
/* process the word array */ for (t = 16; t < 80; t++) {
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP);
}
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
} for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.