// // -------------------------------------------------------------------------- // 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 #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