diff --git a/inc/utils/crypto/sha1.h b/inc/utils/crypto/sha1.h new file mode 100644 index 0000000..c46ad2b --- /dev/null +++ b/inc/utils/crypto/sha1.h @@ -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 + +int sha1_hash(uint8_t *digest, const uint8_t* data, uint64_t len_data); + +#endif //NOXOS_SHA1_H diff --git a/src/boot/kmain.c b/src/boot/kmain.c index 767c801..68c5d84 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -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 } diff --git a/src/utils/crypto/sha1.c b/src/utils/crypto/sha1.c new file mode 100644 index 0000000..5147f23 --- /dev/null +++ b/src/utils/crypto/sha1.c @@ -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 +#include +#include + +#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; +}