esphome_elektromer_han/components/xt211/unused/gxsha1.c

210 lines
6.6 KiB
C

//
// --------------------------------------------------------------------------
// Gurux Ltd
//
//
//
// Filename: $HeadURL$
//
// Version: $Revision$,
// $Date$
// $Author$
//
// Copyright (c) Gurux Ltd
//
//---------------------------------------------------------------------------
//
// DESCRIPTION
//
// This file is a part of Gurux Device Framework.
//
// Gurux Device Framework is Open Source software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; version 2 of the License.
// Gurux Device Framework 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 General Public License for more details.
//
// This code is licensed under the GNU General Public License v2.
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
//---------------------------------------------------------------------------
#include "gxignore.h"
#ifndef DLMS_IGNORE_HIGH_SHA1
#include <string.h>
#include "gxsha1.h"
#define SHA1_ROL(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits))))
#define SHA1_BLK(i) (block[i&15] = SHA1_ROL(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1))
#define SHA1_R0(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
#define SHA1_R1(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + SHA1_BLK(i) + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
#define SHA1_R2(v,w,x,y,z,i) z += (w ^ x ^ y) + SHA1_BLK(i) + 0x6ed9eba1 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
#define SHA1_R3(v,w,x,y,z,i) z += (((w | x) & y) | ( w & x)) + SHA1_BLK(i) + 0x8f1bbcdc + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
#define SHA1_R4(v,w,x,y,z,i) z += (w ^ x ^ y) + SHA1_BLK(i) + 0xca62c1d6 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
/*
* Hash block is a single 512-bit block.
*/
void gxsha1_transform(uint32_t* block, uint32_t* digest, uint32_t* transforms)
{
uint32_t a = digest[0];
uint32_t b = digest[1];
uint32_t c = digest[2];
uint32_t d = digest[3];
uint32_t e = digest[4];
SHA1_R0(a, b, c, d, e, 0);
SHA1_R0(e, a, b, c, d, 1);
SHA1_R0(d, e, a, b, c, 2);
SHA1_R0(c, d, e, a, b, 3);
SHA1_R0(b, c, d, e, a, 4);
SHA1_R0(a, b, c, d, e, 5);
SHA1_R0(e, a, b, c, d, 6);
SHA1_R0(d, e, a, b, c, 7);
SHA1_R0(c, d, e, a, b, 8);
SHA1_R0(b, c, d, e, a, 9);
SHA1_R0(a, b, c, d, e, 10);
SHA1_R0(e, a, b, c, d, 11);
SHA1_R0(d, e, a, b, c, 12);
SHA1_R0(c, d, e, a, b, 13);
SHA1_R0(b, c, d, e, a, 14);
SHA1_R0(a, b, c, d, e, 15);
SHA1_R1(e, a, b, c, d, 16);
SHA1_R1(d, e, a, b, c, 17);
SHA1_R1(c, d, e, a, b, 18);
SHA1_R1(b, c, d, e, a, 19);
SHA1_R2(a, b, c, d, e, 20);
SHA1_R2(e, a, b, c, d, 21);
SHA1_R2(d, e, a, b, c, 22);
SHA1_R2(c, d, e, a, b, 23);
SHA1_R2(b, c, d, e, a, 24);
SHA1_R2(a, b, c, d, e, 25);
SHA1_R2(e, a, b, c, d, 26);
SHA1_R2(d, e, a, b, c, 27);
SHA1_R2(c, d, e, a, b, 28);
SHA1_R2(b, c, d, e, a, 29);
SHA1_R2(a, b, c, d, e, 30);
SHA1_R2(e, a, b, c, d, 31);
SHA1_R2(d, e, a, b, c, 32);
SHA1_R2(c, d, e, a, b, 33);
SHA1_R2(b, c, d, e, a, 34);
SHA1_R2(a, b, c, d, e, 35);
SHA1_R2(e, a, b, c, d, 36);
SHA1_R2(d, e, a, b, c, 37);
SHA1_R2(c, d, e, a, b, 38);
SHA1_R2(b, c, d, e, a, 39);
SHA1_R3(a, b, c, d, e, 40);
SHA1_R3(e, a, b, c, d, 41);
SHA1_R3(d, e, a, b, c, 42);
SHA1_R3(c, d, e, a, b, 43);
SHA1_R3(b, c, d, e, a, 44);
SHA1_R3(a, b, c, d, e, 45);
SHA1_R3(e, a, b, c, d, 46);
SHA1_R3(d, e, a, b, c, 47);
SHA1_R3(c, d, e, a, b, 48);
SHA1_R3(b, c, d, e, a, 49);
SHA1_R3(a, b, c, d, e, 50);
SHA1_R3(e, a, b, c, d, 51);
SHA1_R3(d, e, a, b, c, 52);
SHA1_R3(c, d, e, a, b, 53);
SHA1_R3(b, c, d, e, a, 54);
SHA1_R3(a, b, c, d, e, 55);
SHA1_R3(e, a, b, c, d, 56);
SHA1_R3(d, e, a, b, c, 57);
SHA1_R3(c, d, e, a, b, 58);
SHA1_R3(b, c, d, e, a, 59);
SHA1_R4(a, b, c, d, e, 60);
SHA1_R4(e, a, b, c, d, 61);
SHA1_R4(d, e, a, b, c, 62);
SHA1_R4(c, d, e, a, b, 63);
SHA1_R4(b, c, d, e, a, 64);
SHA1_R4(a, b, c, d, e, 65);
SHA1_R4(e, a, b, c, d, 66);
SHA1_R4(d, e, a, b, c, 67);
SHA1_R4(c, d, e, a, b, 68);
SHA1_R4(b, c, d, e, a, 69);
SHA1_R4(a, b, c, d, e, 70);
SHA1_R4(e, a, b, c, d, 71);
SHA1_R4(d, e, a, b, c, 72);
SHA1_R4(c, d, e, a, b, 73);
SHA1_R4(b, c, d, e, a, 74);
SHA1_R4(a, b, c, d, e, 75);
SHA1_R4(e, a, b, c, d, 76);
SHA1_R4(d, e, a, b, c, 77);
SHA1_R4(c, d, e, a, b, 78);
SHA1_R4(b, c, d, e, a, 79);
digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
digest[4] += e;
++* transforms;
}
void gxsha1_update(gxByteBuffer* data, uint32_t* digest, uint32_t* transforms)
{
unsigned int pos;
uint32_t block[16];
while (data->size - data->position > 64)
{
for (pos = 0; pos != 16; ++pos)
{
bb_getUInt32(data, &block[pos]);
}
gxsha1_transform(block, digest, transforms);
}
}
int gxsha1_final(gxByteBuffer* data, uint32_t* digest, uint32_t* transforms, gxByteBuffer* reply)
{
int pos;
bb_capacity(reply, (uint16_t) *transforms * 64);
bb_set(reply, data->data, data->size);
/* Total number of hashed bits */
uint64_t total_bits = (*transforms * 64 + data->size) * 8;
/* Padding */
bb_setUInt8(reply, 0x80);
uint32_t orig_size = reply->size;
bb_zero(reply, reply->size, 64 - reply->size);
uint32_t block[16];
for (pos = 0; pos != 16; ++pos)
{
bb_getUInt32(reply, &block[pos]);
}
if (orig_size > 64 - 8)
{
gxsha1_transform(block, digest, transforms);
for (pos = 0; pos < 16 - 2; ++pos)
{
block[pos] = 0;
}
}
/* Append total_bits, split this uint64 into two uint32 */
block[16 - 1] = (uint32_t)total_bits;
block[16 - 2] = (uint32_t)(total_bits >> 32);
gxsha1_transform(block, digest, transforms);
bb_capacity(reply, 20);
reply->position = reply->size = 0;
for (pos = 0; pos < 5; ++pos)
{
bb_setUInt32(reply, digest[pos]);
}
return 0;
}
int gxsha1_encrypt(gxByteBuffer* data, gxByteBuffer* result)
{
uint32_t digest[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
uint32_t transforms = 0;
gxsha1_update(data, digest, &transforms);
return gxsha1_final(data, digest, &transforms, result);
}
#endif //DLMS_IGNORE_HIGH_SHA1