⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha1.c

📁 sip协议栈
💻 C
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//** * @CFILE sha1.c * * @par Description *      This file implements the Secure Hashing Algorithm 1 as *      defined in FIPS PUB 180-1 published April 17, 1995. * */#include "config.h"#include "sofia-sip/sha1.h"char const SHA1Copyright[] = "Partly copyright (C) The Internet Society (2001).  All Rights Reserved.\n""\n""This document [RFC3174] and translations of it may be copied and furnished\n""to others, and derivative works that comment on or otherwise explain it or\n""assist in its implementation may be prepared, copied, published and\n""distributed, in whole or in part, without restriction of any kind, provided\n""that the above copyright notice and this paragraph are included on all such\n""copies and derivative works. However, this document itself may not be\n""modified in any way, such as by removing the copyright notice or references\n""to the Internet Society or other Internet organizations, except as needed\n""for the purpose of developing Internet standards in which case the\n""procedures for copyrights defined in the Internet Standards process must be\n""followed, or as required to translate it into languages other than English.\n"  ;/* *  Define the SHA1 circular left shift macro */#define SHA1CircularShift(bits,word) \                (((word) << (bits)) | ((word) >> (32-(bits))))/* Local Function Prototyptes */void SHA1PadMessage(SHA1Context *);void SHA1ProcessMessageBlock(SHA1Context *);/** *      The function SHA1Reset() will initialize the SHA1Context in *      preparation for computing a new SHA1 message digest. * *      @param context [in/out] *          The context to reset. * *  @return *      The function SHA1Reset() returns SHA1 Error Code. * */int SHA1Reset(SHA1Context *context){    if (!context)    {        return shaNull;    }    context->Length_Low             = 0;    context->Length_High            = 0;    context->Message_Block_Index    = 0;    context->Intermediate_Hash[0]   = 0x67452301;    context->Intermediate_Hash[1]   = 0xEFCDAB89;    context->Intermediate_Hash[2]   = 0x98BADCFE;    context->Intermediate_Hash[3]   = 0x10325476;    context->Intermediate_Hash[4]   = 0xC3D2E1F0;    context->Computed   = 0;    context->Corrupted  = 0;    return shaSuccess;}/** *      The function SHA1Result() will return the 160-bit message digest *      into the Message_Digest array provided by the caller. * *      @note The first octet of hash is stored in the 0th element, *            the last octet of hash in the 19th element. * *  @param context [in] *          The context to use to calculate the SHA-1 hash. *  @param Message_Digest [out] *          Where the digest is returned. * *  @returns *      The function SHA1Result() returns SHA1 Error Code. * */int SHA1Result( SHA1Context *context,                uint8_t Message_Digest[SHA1HashSize]){    int i;    if (!context || !Message_Digest)    {        return shaNull;    }    if (context->Corrupted)    {        return context->Corrupted;    }    if (!context->Computed)    {        SHA1PadMessage(context);        for(i=0; i<64; ++i)        {            /* message may be sensitive, clear it out */            context->Message_Block[i] = 0;        }        context->Length_Low = 0;    /* and clear length */        context->Length_High = 0;        context->Computed = 1;    }    for(i = 0; i < SHA1HashSize; ++i)    {        Message_Digest[i] = context->Intermediate_Hash[i>>2]                            >> 8 * ( 3 - ( i & 0x03 ) );    }    return shaSuccess;}/** *      The function SHA1Input() accepts an array of octets as the next portion *      of the message. * *  @param context [in/out] *          The SHA context to update *  @param message_array [in] *          An array of characters representing the next portion of *          the message. *  @param length [in] *          The length of the message in message_array * *  @return *      The function SHA1Input() returns SHA1 Error Code. * */int SHA1Input(    SHA1Context    *context,                  const uint8_t  *message_array,                  unsigned       length){    if (!length)    {        return shaSuccess;    }    if (!context || !message_array)    {        return shaNull;    }    if (context->Computed)    {        context->Corrupted = 1;        return shaStateError;    }    if (context->Corrupted)    {         return context->Corrupted;    }    while(length-- && !context->Corrupted)    {    context->Message_Block[context->Message_Block_Index++] =                    (*message_array & 0xFF);    context->Length_Low += 8;    if (context->Length_Low == 0)    {        context->Length_High++;        if (context->Length_High == 0)        {            /* Message is too long */            context->Corrupted = 1;        }    }    if (context->Message_Block_Index == 64)    {        SHA1ProcessMessageBlock(context);    }    message_array++;    }    return shaSuccess;}/**  * The function SHA1ProcessMessageBlock() will process the next 512 bits of * the message stored in the @a context->Message_Block array. * * @param context [in/out] *      he SHA context to process * * @return *      Nothing. * */void SHA1ProcessMessageBlock(SHA1Context *context){    const uint32_t K[] =    {       /* Constants defined in SHA-1   */                            0x5A827999,                            0x6ED9EBA1,                            0x8F1BBCDC,                            0xCA62C1D6                            };    int           t;                 /* Loop counter                */    uint32_t      temp;              /* Temporary word value        */    uint32_t      W[80];             /* Word sequence               */    uint32_t      A, B, C, D, E;     /* Word buffers                */    /*     *  Initialize the first 16 words in the array W     */    for(t = 0; t < 16; t++)    {        W[t] = context->Message_Block[t * 4] << 24;        W[t] |= context->Message_Block[t * 4 + 1] << 16;        W[t] |= context->Message_Block[t * 4 + 2] << 8;        W[t] |= context->Message_Block[t * 4 + 3];    }    for(t = 16; t < 80; t++)    {       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);    }    A = context->Intermediate_Hash[0];    B = context->Intermediate_Hash[1];    C = context->Intermediate_Hash[2];    D = context->Intermediate_Hash[3];    E = context->Intermediate_Hash[4];    for(t = 0; t < 20; t++)    {        temp =  SHA1CircularShift(5,A) +                ((B & C) | ((~B) & D)) + E + W[t] + K[0];        E = D;        D = C;        C = SHA1CircularShift(30,B);        B = A;        A = temp;    }    for(t = 20; t < 40; t++)    {        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];        E = D;        D = C;        C = SHA1CircularShift(30,B);        B = A;        A = temp;    }    for(t = 40; t < 60; t++)    {        temp = SHA1CircularShift(5,A) +               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];        E = D;        D = C;        C = SHA1CircularShift(30,B);        B = A;        A = temp;    }    for(t = 60; t < 80; t++)    {        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];        E = D;        D = C;        C = SHA1CircularShift(30,B);        B = A;        A = temp;    }    context->Intermediate_Hash[0] += A;    context->Intermediate_Hash[1] += B;    context->Intermediate_Hash[2] += C;    context->Intermediate_Hash[3] += D;    context->Intermediate_Hash[4] += E;    context->Message_Block_Index = 0;}/** *  Pad hashed message. * *      According to the standard, the message must be padded to an even *      512 bits.  The first padding bit must be a '1'.  The last 64 *      bits represent the length of the original message.  All bits in *      between should be 0.  This function will pad the message *      according to those rules by filling the Message_Block array *      accordingly.   * *      It will also call the SHA1ProcessMessageBlock() function. When it *      returns, it can be assumed that the message digest has been *      computed. * *   *  @param context [in/out] *          The context to pad * *  @return *      Nothing. * */void SHA1PadMessage(SHA1Context *context){    /*     *  Check to see if the current message block is too small to hold     *  the initial padding bits and length.  If so, we will pad the     *  block, process it, and then continue padding into a second     *  block.     */    if (context->Message_Block_Index > 55)    {        context->Message_Block[context->Message_Block_Index++] = 0x80;        while(context->Message_Block_Index < 64)        {            context->Message_Block[context->Message_Block_Index++] = 0;        }        SHA1ProcessMessageBlock(context);        while(context->Message_Block_Index < 56)        {            context->Message_Block[context->Message_Block_Index++] = 0;        }    }    else    {        context->Message_Block[context->Message_Block_Index++] = 0x80;        while(context->Message_Block_Index < 56)        {            context->Message_Block[context->Message_Block_Index++] = 0;        }    }    /*     *  Store the message length as the last 8 octets     */    context->Message_Block[56] = context->Length_High >> 24;    context->Message_Block[57] = context->Length_High >> 16;    context->Message_Block[58] = context->Length_High >> 8;    context->Message_Block[59] = context->Length_High;    context->Message_Block[60] = context->Length_Low >> 24;    context->Message_Block[61] = context->Length_Low >> 16;    context->Message_Block[62] = context->Length_Low >> 8;    context->Message_Block[63] = context->Length_Low;    SHA1ProcessMessageBlock(context);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -