feature (crypto): implemented SHA-1

This commit is contained in:
antifallobst 2023-05-26 21:24:23 +02:00
parent fc81e9f458
commit 007851c0ea
3 changed files with 168 additions and 0 deletions

10
inc/utils/crypto/sha1.h Normal file
View File

@ -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

View File

@ -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
}

154
src/utils/crypto/sha1.c Normal file
View File

@ -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;
}