Commit 3a77a8a1 authored by Robert Dubner's avatar Robert Dubner
Browse files

Update SHA and MSCHAP for IPR and formatting

parent 7e72085a
Pipeline #3659 passed with stage
in 40 minutes and 58 seconds
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2021 The OpenLDAP Foundation.
*
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -146,7 +146,7 @@ static const uint8_t permutation_p[32] =
22, 11, 4, 25
};
static const uint8_t inverse_initial[64] =
static const uint8_t inverse_initial[64] =
{
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
......@@ -315,10 +315,10 @@ des_ecb_cycle(uint8_t *out, uint8_t *in, uint8_t *key64)
int column;
row = (s_box_addresses[j][0]<<1) | s_box_addresses[j][5];
column = ( s_box_addresses[j][1]<<3)
| (s_box_addresses[j][2]<<2)
| (s_box_addresses[j][3]<<1)
| s_box_addresses[j][4];
column = ( s_box_addresses[j][1]<<3)
| (s_box_addresses[j][2]<<2)
| (s_box_addresses[j][3]<<1)
| s_box_addresses[j][4];
for(int k=0; k<4; k++)
{
......@@ -347,7 +347,7 @@ des_ecb_cycle(uint8_t *out, uint8_t *in, uint8_t *key64)
// And we are up to the final operation of Figure 1:
permute(out, right_left, inverse_initial, DES_DATA_SIZE);
// And with that, we are done!
}
......
......@@ -129,9 +129,13 @@ GenerateAuthenticatorResponse( uint8_t const *unicode_password,
uint8_t nt_hash_hash[MD4_DIGEST_LENGTH];
// Hash the password
NTPasswordHash(unicode_password, unicode_password_length, nt_hash );
NTPasswordHash( unicode_password,
unicode_password_length,
nt_hash);
// Hash the hash
NTPasswordHash(nt_hash, MD4_DIGEST_LENGTH, nt_hash_hash);
NTPasswordHash( nt_hash,
MD4_DIGEST_LENGTH,
nt_hash_hash);
SHA1Init(&Context);
SHA1Update(&Context, nt_hash_hash, 16);
......@@ -186,12 +190,13 @@ ChallengeHash( const uint8_t *peer_challenge,
}
void
GenerateNTResponse( const uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) // This is the 24-byte returned value
GenerateNTResponse(
const uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) // This is the 24-byte returned value
{
// RFC2759 Section 8.1
uint8_t Challenge[8];
......@@ -209,10 +214,3 @@ GenerateNTResponse( const uint8_t *authenticator_challenge, // 16-byte random
PasswordHash,
NTResponse );
}
......@@ -37,12 +37,13 @@ typedef enum MS_CHAP_OPCODES
MS_CHAP_OPCODE_CHANGE_PASSWORD = 7,
} MS_CHAP_OPCODES;
void GenerateNTResponse(const uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) ; // This is the 24-byte return value
void GenerateNTResponse(
const uint8_t *authenticator_challenge, // 16-byte rand value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) ; // This is the 24-byte return value
void GenerateAuthenticatorResponse( uint8_t const *unicode_password,
ssize_t unicode_password_length,
......
......@@ -60,10 +60,12 @@ A million repetitions of "a"
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \
w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \
w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
......@@ -281,7 +283,8 @@ SHA1Final(
#else
for (i = 0; i < 8; i++)
{
finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
((3 - (i & 3)) * 8)) & 255); /* Endian independent */
}
#endif
c = 0200;
......
......@@ -35,27 +35,23 @@ typedef struct
void SHA1Transform(
uint32_t state[5],
const unsigned char buffer[64]
);
const unsigned char buffer[64]);
void SHA1Init(
SHA1_CTX * context
);
SHA1_CTX * context);
void SHA1Update(
SHA1_CTX * context,
const unsigned char *data,
uint32_t len
);
uint32_t len);
void SHA1Final(
unsigned char digest[20],
SHA1_CTX * context
);
SHA1_CTX * context);
void SHA1(
void SHA1_hash(
char *hash_out,
const char *str,
int len);
#endif /* SHA1_H */
\ No newline at end of file
#endif /* _h_SHA1_H */
......@@ -15,16 +15,11 @@
*
*/
#include "radiusov.h"
#include "lber-int.h"
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDINT_H 1
#include "md4.h"
/** Calculate the MD4 hash of the contents of a buffer
*
* @param[out] out Where to write the MD4 digest. Must be a minimum of MD4_DIGEST_LENGTH.
* @param[in] in Data to hash.
* @param[in] inlen Length of the data.
*/
void
md4_calc(uint8_t out[MD4_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
{
......@@ -169,14 +164,6 @@ md4_update(MD4_CTX *ctx, uint8_t const *in, size_t inlen)
memcpy(ctx->buffer, in, inlen);
}
/** Finalise the MD4 context and write out the hash
*
* Final wrapup - pad to 64-byte boundary with the bit pattern 1 0*
* (64-bit count of bits processed, MSB-first).
*
* @param[out] out Where to write the MD4 digest. Minimum length of MD4_DIGEST_LENGTH.
* @param[in,out] ctx to finalise.
*/
void
md4_final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
{
......@@ -230,7 +217,8 @@ md4_final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
#define F3(x, y, z) (x ^ y ^ z)
/* This is the central step in the MD4 algorithm. */
#define MD4STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s))
#define MD4STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, \
w = w << s | w >> (32 - s))
/** The core of the MD4 algorithm
*
......
......@@ -20,14 +20,13 @@
*
*/
#include "radiusov.h"
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDINT_H 1
#include "md4.h"
#include "mschap.h"
#include "sha1.h"
extern void DesInECBMode( unsigned char *out,
unsigned char const *in,
unsigned char *key );
#include "des.h"
static void
DesEncrypt( uint8_t *Clear,
......@@ -46,8 +45,8 @@ ChallengeResponse( uint8_t *Challenge, // 8 bytes
// See RFC2759 Section 8.5
uint8_t ZPasswordHash [21];
memset(ZPasswordHash, 0, sizeof(ZPasswordHash));
memcpy(ZPasswordHash, PasswordHash, 16);
bzero(ZPasswordHash, sizeof(ZPasswordHash));
bcopy(PasswordHash, ZPasswordHash, 16);
DesEncrypt( Challenge, ZPasswordHash+ 0, Response+ 0);
DesEncrypt( Challenge, ZPasswordHash+ 7, Response+ 8);
......@@ -69,20 +68,21 @@ NTPasswordHash( uint8_t const *unicode_password,
* implements RFC2759 ChallengeHash()
* generates 64 bit challenge
*/
void
mschap_challenge_hash(uint8_t const *peer_challenge,
uint8_t const *auth_challenge,
char const *user_name, uint8_t *challenge )
static void
mschap_challenge_hash(const uint8_t *peer_challenge,
const uint8_t *auth_challenge,
const char *user_name,
uint8_t *challenge )
{
sha1_ctx Context;
SHA1_CTX Context;
uint8_t hash[20];
sha1_init(&Context);
sha1_update(&Context, peer_challenge, 16);
sha1_update(&Context, auth_challenge, 16);
sha1_update(&Context, (uint8_t const *) user_name,
strlen(user_name));
sha1_final(hash, &Context);
SHA1Init(&Context);
SHA1Update(&Context, peer_challenge, 16);
SHA1Update(&Context, auth_challenge, 16);
SHA1Update(&Context, (uint8_t const *) user_name,
strlen(user_name));
SHA1Final(hash, &Context);
memcpy(challenge, hash, 8);
}
......@@ -98,12 +98,11 @@ GenerateAuthenticatorResponse( uint8_t const *unicode_password,
uint8_t const *peer_challenge,
uint8_t const *auth_challenge,
char const *username,
uint8_t *response,
STATE *state)
uint8_t *response)
{
// See RFC2759 Section 8.7
sha1_ctx Context;
SHA1_CTX Context;
static const uint8_t magic1[39] =
{
0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
......@@ -130,26 +129,25 @@ GenerateAuthenticatorResponse( uint8_t const *unicode_password,
uint8_t nt_hash_hash[MD4_DIGEST_LENGTH];
// Hash the password
NTPasswordHash(unicode_password, unicode_password_length, nt_hash );
NTPasswordHash( unicode_password,
unicode_password_length,
nt_hash);
// Hash the hash
NTPasswordHash(nt_hash, MD4_DIGEST_LENGTH, nt_hash_hash);
// We are going to need peer_nt_response and nthashhash in order to create
// the MS-MPPE send and recv keys. Stash them in the state:
memcpy(state->peer_nt_response, ntresponse, 24);
memcpy(state->nthashhash, nt_hash_hash, MD4_DIGEST_LENGTH);
sha1_init(&Context);
sha1_update(&Context, nt_hash_hash, 16);
sha1_update(&Context, ntresponse, 24);
sha1_update(&Context, magic1, 39);
sha1_final(digest, &Context);
NTPasswordHash( nt_hash,
MD4_DIGEST_LENGTH,
nt_hash_hash);
SHA1Init(&Context);
SHA1Update(&Context, nt_hash_hash, 16);
SHA1Update(&Context, ntresponse, 24);
SHA1Update(&Context, magic1, 39);
SHA1Final(digest, &Context);
mschap_challenge_hash(peer_challenge, auth_challenge, username, challenge);
sha1_init(&Context);
sha1_update(&Context, digest, 20);
sha1_update(&Context, challenge, 8);
sha1_update(&Context, magic2, 41);
sha1_final(digest, &Context);
SHA1Init(&Context);
SHA1Update(&Context, digest, 20);
SHA1Update(&Context, challenge, 8);
SHA1Update(&Context, magic2, 41);
SHA1Final(digest, &Context);
/*
* Encode the value of 'Digest' as "S=" followed by
......@@ -172,32 +170,33 @@ GenerateAuthenticatorResponse( uint8_t const *unicode_password,
}
static void
ChallengeHash( uint8_t *peer_challenge,
uint8_t *authenticator_challenge,
char *username,
ChallengeHash( const uint8_t *peer_challenge,
const uint8_t *authenticator_challenge,
const char *username,
uint8_t *Challenge )
{
// RFC2759 Section 8.2
sha1_ctx Context;
sha1_ctx *context = &Context;
SHA1_CTX Context;
SHA1_CTX *context = &Context;
sha1_init(context);
sha1_update(context, peer_challenge, 16);
sha1_update(context, authenticator_challenge, 16);
sha1_update(context, (uint8_t *)username, strlen(username));
SHA1Init(context);
SHA1Update(context, peer_challenge, 16);
SHA1Update(context, authenticator_challenge, 16);
SHA1Update(context, (uint8_t *)username, strlen(username));
uint8_t Digest[20];
sha1_final(Digest, context);
SHA1Final(Digest, context);
memcpy(Challenge, Digest, 8);
}
void
GenerateNTResponse( uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
uint8_t *peer_challenge, // 16-byte random value from authenticating peer
char *username, // 0 to 256-character ASCII username
uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) // This is the 24-byte return value
GenerateNTResponse(
const uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) // This is the 24-byte returned value
{
// RFC2759 Section 8.1
uint8_t Challenge[8];
......@@ -215,12 +214,3 @@ GenerateNTResponse( uint8_t *authenticator_challenge, // 16-byte random value
PasswordHash,
NTResponse );
}
......@@ -17,10 +17,14 @@
*
*/
#ifndef _MSCHAP_H
#define _MSCHAP_H
#ifndef _h_MSCHAP_H
#define _h_MSCHAP_H
#include "tls.h"
#include <sys/types.h>
#include <stdint.h>
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDINT_H 1
#define NT_DIGEST_LENGTH 16
......@@ -33,12 +37,13 @@ typedef enum MS_CHAP_OPCODES
MS_CHAP_OPCODE_CHANGE_PASSWORD = 7,
} MS_CHAP_OPCODES;
void GenerateNTResponse(uint8_t *authenticator_challenge, // 16-byte random value we sent the peer
uint8_t *peer_challenge, // 16-byte random value from authenticating peer
char *username, // 0 to 256-character ASCII username
uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) ; // This is the 24-byte return value
void GenerateNTResponse(
const uint8_t *authenticator_challenge, // 16-byte rand value we sent the peer
const uint8_t *peer_challenge, // 16-byte random value from authenticating peer
const char *username, // 0 to 256-character ASCII username
const uint8_t *unicode_password, // 0 to 256-character 16-bit Unicode password
const size_t unicode_password_length, // length in bytes of the unicode password
uint8_t *NTResponse ) ; // This is the 24-byte return value
void GenerateAuthenticatorResponse( uint8_t const *unicode_password,
ssize_t unicode_password_length,
......@@ -46,8 +51,7 @@ void GenerateAuthenticatorResponse( uint8_t const *unicode_password,
uint8_t const *peer_challenge,
uint8_t const *auth_challenge,
char const *username,
uint8_t *response,
STATE *state );
uint8_t *response);
typedef struct _MSCHAP_CHALLENGE
{
......@@ -71,30 +75,48 @@ typedef struct _SUB_RESPONSE
{
// The length of this structure is 49 bytes
uint8_t Peer_Challenge[16]; // Sixteen random bytes
uint8_t Reserved[6]; // Must be zero
uint8_t Reserved[8]; // Must be zero
uint8_t NT_Response[24]; // See RFC2759, Section 8.1
uint8_t Flags; // Must be zero
} SUB_RESPONSE;
#define NOMINAL_SIZE_OF_MSCHAP_RESPONSE (49+6)
typedef struct _MSCHAP_RESPONSE
{
// See https://datatracker.ietf.org/doc/html/draft-kamath-pppext-eap-mschapv2-02
// section 2.1 Our data to be encrypted starts at Type, which is the fourth byte
// of the response packet as documented. (The documentation didn't anticipate
// that the data would be encrypted and sent in EAP-Messages.)
uint8_t Type; // 26 for EAP MS-CHAP-V2
uint8_t OpCode; // 2 for response
uint8_t MS_Chap_ID; // Typically the same as the containing EAP-Message identifier
uint8_t MS_Length[8]; // Big-endian
uint8_t Value_Size; // This will/should be 0x31 (decimal 49)
SUB_RESPONSE SubResponse; // See above
uint8_t Name[1]; // Might not be there at all. Not NULL or CR/LF terminated.
// // The length is inferred: MS_Length - Value_Size - 6
uint8_t Type; // 26 for EAP MS-CHAP-V2
uint8_t OpCode; // 2 for response
uint8_t MS_Chap_ID; // Typically the same as the containing EAP-Message identifier
uint8_t MS_Length[2]; // Big-endian
uint8_t Value_Size; // This will/should be 0x31 (decimal 49)
SUB_RESPONSE SubResponse; // See above
uint8_t Name[1]; // Might not be there at all. Not NULL or CR/LF terminated.
// // The length is inferred: MS_Length - Value_Size - 6
} MSCHAP_RESPONSE;
// Rather than create another set of files, I decided to piggyback the
// EAP-TTLS definitions onto this mschap.h file
// See rfc5281, section 10.1
#define TTLS_HEADER_SIZE 8
#define EAP_OVERHEAD_SIZE 5
#define TTLS_LENGTH_OFFSET 6
#define EAP_LENGTH_OFFSET 10
#define EAP_USERNAME_OFFSET 13
typedef struct _TTLS_BLOCK
{
uint8_t AVP_Code[4]; // big-endian attribute-value pair Code
uint8_t AVP_Flags; // 0x80 means there is a Vendor ID
uint8_t AVP_Length[3];
uint8_t AVP_Data[1]; // If the Vendor flag is on, then there are four bytes
// // of VendorID before the data
} TTLS_BLOCK;
#endif
\ No newline at end of file
......@@ -44,13 +44,15 @@ SendThePacket( RADIUS_PACKET *response,
GV_packet_count += 1;
Debug( LDAP_DEBUG_ARGS | LDAP_DEBUG_PACKETS | LDAP_DEBUG_CONNS,
DPREFIX "%s(): sending %ld bytes *************************** Nominal packet #%d\n",
DPREFIX "%s(): sending %ld bytes "
"*************************** Nominal packet #%d\n",
__func__,
length,
GV_packet_count);
// During development and debugging, I sometimes ended up with zero-length packets.
// This wasn't a big problem, but there was no point in confusing the TCP/IP stack.
// During development and debugging, I sometimes ended up with zero-length
// packets. This wasn't a big problem, but there was no point in confusing
// the TCP/IP stack.
if( length )
{
debugging_display_of(response);
......@@ -1144,8 +1146,7 @@ process_mschap_response(STATE *state)
peer_challenge,
authenticator_challenge,
p_username,
AuthenticatorResponse,
state);
AuthenticatorResponse);
// We can now build the MS-CHAPv2 Success response to be encrypted:
......
......@@ -16,150 +16,194 @@
*
*/
#include "radiusov.h"
#include "lber-int.h"
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#define SHA1HANDSOFF
#include <stdio.h>
#include <string.h>
/* for uint32_t */
#include <stdint.h>
#include "sha1.h"
# define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
# define blk0(i) (block->l[i] = htonl(block->l[i]))
# define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
#if BYTE_ORDER == LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#elif BYTE_ORDER == BIG_ENDIAN
#define blk0(i) block->l[i]
#else
#error "Endianness not defined!"
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
# define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
# define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
# define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
# define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
# define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \
w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \
w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void
sha1_transform(uint32_t state[5], uint8_t const buffer[64])
SHA1Transform(
uint32_t state[5],
const unsigned char buffer[64]
)