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

📄 mech_sha.c

📁 IBM的Linux上的PKCS#11实现
💻 C
📖 第 1 页 / 共 3 页
字号:
   }done:   sign_mgr_cleanup( &hmac_ctx );   return rc;}//// CKM routines//////CK_RVckm_sha1_update( DIGEST_CONTEXT * ctx,                 CK_BYTE        * in_data,                 CK_ULONG         in_data_len ){    if( token_specific.t_sha_update == NULL ){	if (!ctx || !in_data){	    st_err_log(4, __FILE__, __LINE__, __FUNCTION__);	    return CKR_FUNCTION_FAILED;	}	shaUpdate( (SHA1_CONTEXT *)ctx->context, in_data, in_data_len );	return CKR_OK;    }    return token_specific.t_sha_update(ctx, in_data, in_data_len);}////CK_RVckm_sha1_final( DIGEST_CONTEXT * ctx,                CK_BYTE        * out_data,                CK_ULONG       * out_data_len ){    if (token_specific.t_sha_final  == NULL ){	if (!ctx || !out_data || !out_data_len){	    st_err_log(4, __FILE__, __LINE__, __FUNCTION__);	    return CKR_FUNCTION_FAILED;	}	if (*out_data_len < SHA1_HASH_SIZE){	    st_err_log(4, __FILE__, __LINE__, __FUNCTION__);	    return CKR_FUNCTION_FAILED;	}	shaFinal( (SHA1_CONTEXT *)ctx->context, out_data );	*out_data_len = SHA1_HASH_SIZE;	return CKR_OK;    }         return token_specific.t_sha_final(ctx, out_data, out_data_len);}//// Software SHA-1 implementation//voidckm_sha1_init( DIGEST_CONTEXT * ctx){    // Set the h-vars to their initial values    if (token_specific.t_sha_init  == NULL ) {	SHA1_CONTEXT *sha1_ctx;	/* Allocate the context */	ctx->context_len = sizeof(SHA1_CONTEXT);	ctx->context = (CK_BYTE *)malloc(sizeof(SHA1_CONTEXT));	if( ctx->context == NULL )		return;    	sha1_ctx = (SHA1_CONTEXT *)ctx->context;	sha1_ctx->hash_value[0]  = h0init;	sha1_ctx->hash_value[1]  = h1init;	sha1_ctx->hash_value[2]  = h2init;	sha1_ctx->hash_value[3]  = h3init;	sha1_ctx->hash_value[4]  = h4init;	// Initialise bit count    	sha1_ctx->bits_lo = sha1_ctx->bits_hi = 0;    } else {	// SAB XXX call token specific init... the init MUST allocate it's context	token_specific.t_sha_init(ctx);    }}// Perform the SHA transformation.  Note that this code, like MD5, seems to// break some optimizing compilers due to the complexity of the expressions// and the size of the basic block.  It may be necessary to split it into// sections, e.g. based on the four subrounds//// Note that this corrupts the sha->data area//voidshaTransform( SHA1_CONTEXT *ctx ){   register unsigned int A, B, C, D, E;   // Set up first buffer   //   A = ctx->hash_value[0];   B = ctx->hash_value[1];   C = ctx->hash_value[2];   D = ctx->hash_value[3];   E = ctx->hash_value[4];   // Heavy mangling, in 4 sub-rounds of 20 interations each.   //   subRound( A, B, C, D, E, f1, K1, ctx->buf[ 0] );   subRound( E, A, B, C, D, f1, K1, ctx->buf[ 1] );   subRound( D, E, A, B, C, f1, K1, ctx->buf[ 2] );   subRound( C, D, E, A, B, f1, K1, ctx->buf[ 3] );   subRound( B, C, D, E, A, f1, K1, ctx->buf[ 4] );   subRound( A, B, C, D, E, f1, K1, ctx->buf[ 5] );   subRound( E, A, B, C, D, f1, K1, ctx->buf[ 6] );   subRound( D, E, A, B, C, f1, K1, ctx->buf[ 7] );   subRound( C, D, E, A, B, f1, K1, ctx->buf[ 8] );   subRound( B, C, D, E, A, f1, K1, ctx->buf[ 9] );   subRound( A, B, C, D, E, f1, K1, ctx->buf[10] );   subRound( E, A, B, C, D, f1, K1, ctx->buf[11] );   subRound( D, E, A, B, C, f1, K1, ctx->buf[12] );   subRound( C, D, E, A, B, f1, K1, ctx->buf[13] );   subRound( B, C, D, E, A, f1, K1, ctx->buf[14] );   subRound( A, B, C, D, E, f1, K1, ctx->buf[15] );   subRound( E, A, B, C, D, f1, K1, expand(ctx->buf, 16) );   subRound( D, E, A, B, C, f1, K1, expand(ctx->buf, 17) );   subRound( C, D, E, A, B, f1, K1, expand(ctx->buf, 18) );   subRound( B, C, D, E, A, f1, K1, expand(ctx->buf, 19) );   subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 20) );   subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 21) );   subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 22) );   subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 23) );   subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 24) );   subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 25) );   subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 26) );   subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 27) );   subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 28) );   subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 29) );   subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 30) );   subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 31) );   subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 32) );   subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 33) );   subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 34) );   subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 35) );   subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 36) );   subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 37) );   subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 38) );   subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 39) );   subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 40) );   subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 41) );   subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 42) );   subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 43) );   subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 44) );   subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 45) );   subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 46) );   subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 47) );   subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 48) );   subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 49) );   subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 50) );   subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 51) );   subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 52) );   subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 53) );   subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 54) );   subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 55) );   subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 56) );   subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 57) );   subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 58) );   subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 59) );   subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 60) );   subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 61) );   subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 62) );   subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 63) );   subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 64) );   subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 65) );   subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 66) );   subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 67) );   subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 68) );   subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 69) );   subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 70) );   subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 71) );   subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 72) );   subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 73) );   subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 74) );   subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 75) );   subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 76) );   subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 77) );   subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 78) );   subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 79) );   // Build message digest   //   ctx->hash_value[0] += A;   ctx->hash_value[1] += B;   ctx->hash_value[2] += C;   ctx->hash_value[3] += D;   ctx->hash_value[4] += E;}// SHA is defined in big-endian form, so this converts the buffer from// bytes to words, independent of the machine's native endianness.//// Assuming a consistent byte ordering for the machine, this also// has the magic property of being self-inverse.  It is used as// such.//static voidbyteReverse( unsigned int *buffer,             unsigned int  byteCount ){#ifndef __BYTE_ORDER#error  "Endianess MUST be defined"#endif#if  __BYTE_ORDER == __LITTLE_ENDIAN   CK_ULONG value, val;   byteCount /= sizeof(CK_ULONG_32);   while (byteCount--) {      val = *buffer;      value = ((0x000000FF & val) << 24) |              ((0x0000FF00 & val) << 8 ) |              ((0x00FF0000 & val) >> 8 ) |              ((0xFF000000 & val) >> 24);      *buffer++ = value;   }#endif// JRM - this code gives funky results on Linux/Intel.//       I assume this is a GCC issue since regression tests passed on NT////   byteCount /= sizeof(CK_ULONG);//   while ( byteCount-- ) {//      value = (CK_ULONG)((unsigned)((CK_BYTE *)buffer)[0] << 8 | ((CK_BYTE *)buffer)[1]) << 16 |//                        ((unsigned)((CK_BYTE *)buffer)[2] << 8 | ((CK_BYTE *)buffer)[3]);//      *buffer++ = value;//   }}voidshaUpdate( SHA1_CONTEXT      * ctx,           CK_BYTE const     * buffer,           CK_ULONG            count){   CK_ULONG t;   // Update bitcount   //   t = ctx->bits_lo;   if ((ctx->bits_lo = t + count) < t)      ctx->bits_hi++;   // Carry from low to high   t &= 0x3f;  // Bytes already in ctx->buf   // Handle any leading odd-sized chunks   //   if (t) {      CK_BYTE *p = (CK_BYTE *)ctx->buf + t;      t = 64-t;      if (count < t) {         memcpy(p, buffer, count);         return;      }      memcpy(p, buffer, t);      byteReverse(ctx->buf, SHA1_BLOCK_SIZE);      shaTransform(ctx);      buffer += t;      count -= t;   }   // Process data in SHA1_BLOCK_SIZE chunks   //   while (count >= SHA1_BLOCK_SIZE) {      memcpy(ctx->buf, buffer, SHA1_BLOCK_SIZE);      byteReverse(ctx->buf, SHA1_BLOCK_SIZE);      shaTransform(ctx);      buffer += SHA1_BLOCK_SIZE;      count -= SHA1_BLOCK_SIZE;   }   // Handle any remaining bytes of data.   //   memcpy(ctx->buf, buffer, count);}// Final wrapup - pad to 64-byte boundary with the bit pattern// 1 0* (64-bit count of bits processed, MSB-first)//voidshaFinal( SHA1_CONTEXT * ctx,          CK_BYTE      * hash ){   int count;   CK_BYTE *p;   // Compute number of bytes mod 64   //   count = (int)ctx->bits_lo & 0x3F;   // Set the first char of padding to 0x80.   // This is safe since there is always at least one byte free   //   p = (CK_BYTE *)ctx->buf + count;   *p++ = 0x80;   // Bytes of padding needed to make 64 bytes   //   count = SHA1_BLOCK_SIZE - 1 - count;   // Pad out to 56 mod 64   //   if (count < 8) {      // Two lots of padding:  Pad the first block to 64 bytes      //      memset(p, 0, count);      byteReverse(ctx->buf, SHA1_BLOCK_SIZE);      shaTransform(ctx);      // Now fill the next block with 56 bytes      //      memset(ctx->buf, 0, SHA1_BLOCK_SIZE-8);   } else {      // Pad block to 56 bytes      //      memset(p, 0, count-8);   }   byteReverse(ctx->buf, SHA1_BLOCK_SIZE-8);   // Append length in *bits* and transform   //   ctx->buf[14] = ctx->bits_hi << 3 | ctx->bits_lo >> 29;   ctx->buf[15] = ctx->bits_lo << 3;   shaTransform(ctx);   // Store output hash in buffer   //   byteReverse(ctx->hash_value, SHA1_HASH_SIZE);   memcpy(hash, ctx->hash_value, SHA1_HASH_SIZE);}

⌨️ 快捷键说明

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