Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:19 2009

## Asterisk developer's documentation

# sha1.c File Reference

`#include "asterisk/sha1.h"`

Include dependency graph for sha1.c:

Go to the source code of this file.

## Defines

#define | SHA1CircularShift(bits, word) (((word) << (bits)) | ((word) >> (32-(bits))))

## Functions

int | SHA1Input (SHA1Context *context, const uint8_t *message_array, unsigned length)
void | SHA1PadMessage (SHA1Context *)
void | SHA1ProcessMessageBlock (SHA1Context *)
int | SHA1Reset (SHA1Context *context)
int | SHA1Result (SHA1Context *context, uint8_t Message_Digest[SHA1HashSize])

## Define Documentation

#define SHA1CircularShift | ( | bits,
|  | word |  | ) | (((word) << (bits)) | ((word) >> (32-(bits))))

Definition at line 69 of file sha1.c.

Referenced by SHA1ProcessMessageBlock().

## Function Documentation

int SHA1Input | ( | SHA1Context * | context,
|  | const uint8_t * | message_array,
|  | unsigned | length |
| ) |  |  |

Definition at line 183 of file sha1.c.

References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, SHA1ProcessMessageBlock(), shaNull, shaStateError, and shaSuccess.

Referenced by ast_sha1_hash().

    00184 {
    00185    if (!length) {
    00186       return shaSuccess;
    00187    }
    00188
    00189    if (!context || !message_array) {
    00190       return shaNull;
    00191    }
    00192
    00193    if (context->Computed) {
    00194       context->Corrupted = shaStateError;
    00195       return shaStateError;
    00196    }
    00197
    00198    if (context->Corrupted) {
    00199       return context->Corrupted;
    00200    }
    00201
    00202    while (length-- && !context->Corrupted) {
    00203       context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
    00204
    00205       context->Length_Low += 8;
    00206       if (context->Length_Low == 0) {
    00207          context->Length_High++;
    00208          if (context->Length_High == 0) {
    00209             /* Message is too long */
    00210             context->Corrupted = 1;
    00211          }
    00212       }
    00213
    00214       if (context->Message_Block_Index == 64) {
    00215          SHA1ProcessMessageBlock(context);
    00216       }
    00217
    00218       message_array++;
    00219    }
    00220
    00221    return shaSuccess;
    00222 }

void SHA1PadMessage | ( | SHA1Context * | context | ) |

Definition at line 346 of file sha1.c.

References SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, and SHA1ProcessMessageBlock().

Referenced by SHA1Result().

    00347 {
    00348    /*
    00349     *  Check to see if the current message block is too small to hold
    00350     *  the initial padding bits and length.  If so, we will pad the
    00351     *  block, process it, and then continue padding into a second
    00352     *  block.
    00353     */
    00354    if (context->Message_Block_Index > 55) {
    00355       context->Message_Block[context->Message_Block_Index++] = 0x80;
    00356       while (context->Message_Block_Index < 64) {
    00357          context->Message_Block[context->Message_Block_Index++] = 0;
    00358       }
    00359
    00360       SHA1ProcessMessageBlock(context);
    00361
    00362       while (context->Message_Block_Index < 56) {
    00363          context->Message_Block[context->Message_Block_Index++] = 0;
    00364       }
    00365    } else {
    00366       context->Message_Block[context->Message_Block_Index++] = 0x80;
    00367       while (context->Message_Block_Index < 56) {
    00368          context->Message_Block[context->Message_Block_Index++] = 0;
    00369       }
    00370    }
    00371
    00372    /*
    00373     *  Store the message length as the last 8 octets
    00374     */
    00375    context->Message_Block[56] = context->Length_High >> 24;
    00376    context->Message_Block[57] = context->Length_High >> 16;
    00377    context->Message_Block[58] = context->Length_High >> 8;
    00378    context->Message_Block[59] = context->Length_High;
    00379    context->Message_Block[60] = context->Length_Low >> 24;
    00380    context->Message_Block[61] = context->Length_Low >> 16;
    00381    context->Message_Block[62] = context->Length_Low >> 8;
    00382    context->Message_Block[63] = context->Length_Low;
    00383
    00384    SHA1ProcessMessageBlock(context);
    00385 }

void SHA1ProcessMessageBlock | ( | SHA1Context * | context | ) |

Definition at line 244 of file sha1.c.

References SHA1Context::Intermediate_Hash, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, SHA1CircularShift, and t.

Referenced by SHA1Input(), and SHA1PadMessage().

    00245 {
    00246    const uint32_t K[] =     {     /* Constants defined in SHA-1  */
    00247                             0x5A827999,
    00248                             0x6ED9EBA1,
    00249                             0x8F1BBCDC,
    00250                             0xCA62C1D6
    00251                             };
    00252    int           t;                 /* Loop counter                */
    00253    uint32_t    temp;              /* Temporary word value        */
    00254    uint32_t    W[80];             /* Word sequence               */
    00255    uint32_t    A, B, C, D, E;     /* Word buffers                */
    00256
    00257    /*
    00258     *  Initialize the first 16 words in the array W
    00259     */
    00260    for (t = 0; t < 16; t++) {
    00261       W[t] = context->Message_Block[t * 4] << 24;
    00262       W[t] |= context->Message_Block[t * 4 + 1] << 16;
    00263       W[t] |= context->Message_Block[t * 4 + 2] << 8;
    00264       W[t] |= context->Message_Block[t * 4 + 3];
    00265    }
    00266
    00267    for (t = 16; t < 80; t++) {
    00268       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    00269    }
    00270
    00271    A = context->Intermediate_Hash[0];
    00272    B = context->Intermediate_Hash[1];
    00273    C = context->Intermediate_Hash[2];
    00274    D = context->Intermediate_Hash[3];
    00275    E = context->Intermediate_Hash[4];
    00276
    00277    for (t = 0; t < 20; t++) {
    00278       temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
    00279       E = D;
    00280       D = C;
    00281       C = SHA1CircularShift(30,B);
    00282       B = A;
    00283       A = temp;
    00284    }
    00285
    00286    for (t = 20; t < 40; t++) {
    00287       temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
    00288       E = D;
    00289       D = C;
    00290       C = SHA1CircularShift(30,B);
    00291       B = A;
    00292       A = temp;
    00293    }
    00294
    00295    for (t = 40; t < 60; t++) {
    00296       temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
    00297       E = D;
    00298       D = C;
    00299       C = SHA1CircularShift(30,B);
    00300       B = A;
    00301       A = temp;
    00302    }
    00303
    00304    for (t = 60; t < 80; t++) {
    00305       temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
    00306       E = D;
    00307       D = C;
    00308       C = SHA1CircularShift(30,B);
    00309       B = A;
    00310       A = temp;
    00311    }
    00312
    00313    context->Intermediate_Hash[0] += A;
    00314    context->Intermediate_Hash[1] += B;
    00315    context->Intermediate_Hash[2] += C;
    00316    context->Intermediate_Hash[3] += D;
    00317    context->Intermediate_Hash[4] += E;
    00318
    00319    context->Message_Block_Index = 0;
    00320 }

int SHA1Reset | ( | SHA1Context * | context | ) |

Definition at line 91 of file sha1.c.

References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Intermediate_Hash, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block_Index, shaNull, and shaSuccess.

Referenced by ast_sha1_hash().

    00092 {
    00093    if (!context) {
    00094       return shaNull;
    00095    }
    00096
    00097    context->Length_Low             = 0;
    00098    context->Length_High            = 0;
    00099    context->Message_Block_Index    = 0;
    00100
    00101    context->Intermediate_Hash[0]   = 0x67452301;
    00102    context->Intermediate_Hash[1]   = 0xEFCDAB89;
    00103    context->Intermediate_Hash[2]   = 0x98BADCFE;
    00104    context->Intermediate_Hash[3]   = 0x10325476;
    00105    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
    00106
    00107    context->Computed               = 0;
    00108    context->Corrupted              = 0;
    00109
    00110    return shaSuccess;
    00111 }

int SHA1Result | ( | SHA1Context * | context,
|  | uint8_t | Message_Digest[SHA1HashSize] |
| ) |  |  |

Definition at line 132 of file sha1.c.

References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Intermediate_Hash, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1PadMessage(), shaNull, and shaSuccess.

Referenced by ast_sha1_hash().

    00134 {
    00135    int i;
    00136
    00137    if (!context || !Message_Digest) {
    00138       return shaNull;
    00139    }
    00140
    00141    if (context->Corrupted) {
    00142       return context->Corrupted;
    00143    }
    00144
    00145    if (!context->Computed) {
    00146       SHA1PadMessage(context);
    00147       for (i = 0; i < 64; ++i) {
    00148          /* message may be sensitive, clear it out */
    00149          context->Message_Block[i] = 0;
    00150       }
    00151       context->Length_Low = 0;    /* and clear length */
    00152       context->Length_High = 0;
    00153       context->Computed = 1;
    00154    }
    00155
    00156    for (i = 0; i < SHA1HashSize; ++i) {
    00157       Message_Digest[i] = context->Intermediate_Hash[i >> 2] >> 8 * ( 3 - ( i & 0x03 ) );
    00158    }
    00159
    00160    return shaSuccess;
    00161 }