feature (crypto): implemented SHA-1
This commit is contained in:
parent
fc81e9f458
commit
007851c0ea
|
@ -0,0 +1,10 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
|
||||
#ifndef NOXOS_SHA1_H
|
||||
#define NOXOS_SHA1_H
|
||||
|
||||
#include <utils/stdtypes.h>
|
||||
|
||||
int sha1_hash(uint8_t *digest, const uint8_t* data, uint64_t len_data);
|
||||
|
||||
#endif //NOXOS_SHA1_H
|
|
@ -3,6 +3,7 @@
|
|||
#include "utils/logger.h"
|
||||
#include "utils/core.h"
|
||||
#include "utils/memory.h"
|
||||
#include "utils/crypto/sha1.h"
|
||||
#include "boot/boot_info.h"
|
||||
#include "boot/config.h"
|
||||
#include "platform/interrupts.h"
|
||||
|
@ -84,5 +85,8 @@ void kmain(boot_info_T boot_info) {
|
|||
|
||||
syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0);
|
||||
|
||||
uint8_t digest[20];
|
||||
sha1_hash(digest, "test", 4);
|
||||
|
||||
CORE_HALT_FOREVER
|
||||
}
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
// This implementation of the SHA-1 algorithm is from https://github.com/CTrabant/teeny-sha1
|
||||
|
||||
#include <utils/crypto/sha1.h>
|
||||
#include <utils/memory.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
#define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
int sha1_hash(uint8_t digest[20], const uint8_t* data, uint64_t len_data) {
|
||||
|
||||
uint32_t W[80];
|
||||
uint32_t H[] = {0x67452301,
|
||||
0xEFCDAB89,
|
||||
0x98BADCFE,
|
||||
0x10325476,
|
||||
0xC3D2E1F0};
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
uint32_t e;
|
||||
uint32_t f = 0;
|
||||
uint32_t k = 0;
|
||||
|
||||
uint32_t idx;
|
||||
uint32_t lidx;
|
||||
uint32_t widx;
|
||||
uint32_t didx = 0;
|
||||
|
||||
int32_t wcount;
|
||||
uint32_t temp;
|
||||
uint64_t databits = ((uint64_t)len_data) * 8;
|
||||
uint32_t loopcount = (len_data + 8) / 64 + 1;
|
||||
uint32_t tailbytes = 64 * loopcount - len_data;
|
||||
uint8_t datatail[128] = {0};
|
||||
|
||||
if (!digest)
|
||||
return -1;
|
||||
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
/* Pre-processing of data tail (includes padding to fill out 512-bit chunk):
|
||||
Add bit '1' to end of message (big-endian)
|
||||
Add 64-bit message length in bits at very end (big-endian) */
|
||||
datatail[0] = 0x80;
|
||||
datatail[tailbytes - 8] = (uint8_t) (databits >> 56 & 0xFF);
|
||||
datatail[tailbytes - 7] = (uint8_t) (databits >> 48 & 0xFF);
|
||||
datatail[tailbytes - 6] = (uint8_t) (databits >> 40 & 0xFF);
|
||||
datatail[tailbytes - 5] = (uint8_t) (databits >> 32 & 0xFF);
|
||||
datatail[tailbytes - 4] = (uint8_t) (databits >> 24 & 0xFF);
|
||||
datatail[tailbytes - 3] = (uint8_t) (databits >> 16 & 0xFF);
|
||||
datatail[tailbytes - 2] = (uint8_t) (databits >> 8 & 0xFF);
|
||||
datatail[tailbytes - 1] = (uint8_t) (databits >> 0 & 0xFF);
|
||||
|
||||
/* Process each 512-bit chunk */
|
||||
for (lidx = 0; lidx < loopcount; lidx++)
|
||||
{
|
||||
/* Compute all elements in W */
|
||||
memory_set(W, 0, 80 * sizeof (uint32_t));
|
||||
|
||||
/* Break 512-bit chunk into sixteen 32-bit, big endian words */
|
||||
for (widx = 0; widx <= 15; widx++)
|
||||
{
|
||||
wcount = 24;
|
||||
|
||||
/* Copy byte-per byte from specified buffer */
|
||||
while (didx < len_data && wcount >= 0)
|
||||
{
|
||||
W[widx] += (((uint32_t)data[didx]) << wcount);
|
||||
didx++;
|
||||
wcount -= 8;
|
||||
}
|
||||
/* Fill out W with padding as needed */
|
||||
while (wcount >= 0)
|
||||
{
|
||||
W[widx] += (((uint32_t)datatail[didx - len_data]) << wcount);
|
||||
didx++;
|
||||
wcount -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extend the sixteen 32-bit words into eighty 32-bit words, with potential optimization from:
|
||||
"Improving the Performance of the Secure Hash Algorithm (SHA-1)" by Max Locktyukhin */
|
||||
for (widx = 16; widx <= 31; widx++)
|
||||
{
|
||||
W[widx] = SHA1ROTATELEFT ((W[widx - 3] ^ W[widx - 8] ^ W[widx - 14] ^ W[widx - 16]), 1);
|
||||
}
|
||||
for (widx = 32; widx <= 79; widx++)
|
||||
{
|
||||
W[widx] = SHA1ROTATELEFT ((W[widx - 6] ^ W[widx - 16] ^ W[widx - 28] ^ W[widx - 32]), 2);
|
||||
}
|
||||
|
||||
/* Main loop */
|
||||
a = H[0];
|
||||
b = H[1];
|
||||
c = H[2];
|
||||
d = H[3];
|
||||
e = H[4];
|
||||
|
||||
for (idx = 0; idx <= 79; idx++)
|
||||
{
|
||||
if (idx <= 19)
|
||||
{
|
||||
f = (b & c) | ((~b) & d);
|
||||
k = 0x5A827999;
|
||||
}
|
||||
else if (idx >= 20 && idx <= 39)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0x6ED9EBA1;
|
||||
}
|
||||
else if (idx >= 40 && idx <= 59)
|
||||
{
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = 0x8F1BBCDC;
|
||||
}
|
||||
else if (idx >= 60 && idx <= 79)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
temp = SHA1ROTATELEFT (a, 5) + f + e + k + W[idx];
|
||||
e = d;
|
||||
d = c;
|
||||
c = SHA1ROTATELEFT (b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
}
|
||||
|
||||
/* Store binary digest in supplied buffer */
|
||||
if (digest)
|
||||
{
|
||||
for (idx = 0; idx < 5; idx++)
|
||||
{
|
||||
digest[idx * 4 + 0] = (uint8_t) (H[idx] >> 24);
|
||||
digest[idx * 4 + 1] = (uint8_t) (H[idx] >> 16);
|
||||
digest[idx * 4 + 2] = (uint8_t) (H[idx] >> 8);
|
||||
digest[idx * 4 + 3] = (uint8_t) (H[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("hex digest: %xd%xd%xd%xd%xd", H[0], H[1], H[2], H[3], H[4]);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue