os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit bb5d24687081b90d7d253bab111b6f92b077413f
parent 04eb516326c4ea9ca489a392a76c90213d63314d
Author: erai <erai@omiltem.net>
Date:   Wed,  8 May 2024 19:34:10 -0400

Add sha256

Diffstat:
Mlib.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asha256.c | 459+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asha256_test.c | 7+++++++
3 files changed, 554 insertions(+), 0 deletions(-)

diff --git a/lib.c b/lib.c @@ -97,6 +97,32 @@ fdputh(fd: int, n: int) { } } +fdputhn(fd: int, x: int, d: int) { + loop { + if d == 0 { + break; + } + d = d - 4; + fdputc(fd, "0123456789abcdef"[(x >> d) & 15]:int); + } +} + +fdputh8(fd: int, x: int) { + fdputhn(fd, x, 8); +} + +fdputh16(fd: int, x: int) { + fdputhn(fd, x, 16); +} + +fdputh32(fd: int, x: int) { + fdputhn(fd, x, 32); +} + +fdputh64(fd: int, x: int) { + fdputhn(fd, x, 64); +} + fdputd(fd: int, n: int) { var a: int; @@ -115,3 +141,65 @@ fdputd(fd: int, n: int) { fdputc(fd, '0' + a); } + +fdxxd(fd: int, data: *byte, len: int) { + var i: int; + var j: int; + loop { + if i >= len { + break; + } + + fdputh32(fd, i); + + fdputc(fd, ':'); + fdputc(fd, ' '); + + j = 0; + + loop { + if j == 16 { + break; + } + + if i + j < len { + fdputh8(fd, data[i + j]: int); + } else { + fdputc(fd, ' '); + fdputc(fd, ' '); + } + + if i + j + 1 < len { + fdputh8(fd, data[i + j + 1]: int); + } else { + fdputc(fd, ' '); + fdputc(fd, ' '); + } + + fdputc(fd, ' '); + + j = j + 2; + } + + fdputc(fd, ' '); + + j = 0; + loop { + if j == 16 || i + j >= len { + break; + } + + if data[i + j]:int >= 0x20 && data[i + j]:int < 0x80 { + fdputc(fd, data[i + j]: int); + } else { + fdputc(fd, '.'); + } + + j = j + 1; + } + + fdputc(fd, '\n'); + + i = i + 16; + } +} diff --git a/sha256.c b/sha256.c @@ -0,0 +1,459 @@ +// https://www.rfc-editor.org/rfc/rfc4634 + +struct sha256_ctx { + a: int; + b: int; + c: int; + d: int; + e: int; + f: int; + g: int; + h: int; +} + +struct sha256_w { + w0: int; + w1: int; + w2: int; + w3: int; + w4: int; + w5: int; + w6: int; + w7: int; + w8: int; + w9: int; + w10: int; + w11: int; + w12: int; + w13: int; + w14: int; + w15: int; + w16: int; + w17: int; + w18: int; + w19: int; + w20: int; + w21: int; + w22: int; + w23: int; + w24: int; + w25: int; + w26: int; + w27: int; + w28: int; + w29: int; + w30: int; + w31: int; +} + +struct _sha256_digest { + d0: int; + d1: int; + d2: int; + d3: int; + d4: int; + d5: int; + d6: int; + d7: int; +} + +sha256_init(r: *sha256_ctx) { + r.a = (0x6a09 << 16) | 0xe667; + r.b = (0xbb67 << 16) | 0xae85; + r.c = (0x3c6e << 16) | 0xf372; + r.d = (0xa54f << 16) | 0xf53a; + r.e = (0x510e << 16) | 0x527f; + r.f = (0x9b05 << 16) | 0x688c; + r.g = (0x1f83 << 16) | 0xd9ab; + r.h = (0x5be0 << 16) | 0xcd19; +} + +ror32(x: int, n: int): int { + return ((x >> n) | (x << (32 - n))) & (-1 >> 32); +} + +sha256_round(ctx: *sha256_ctx, w: *int, k: int) { + var t1: int; + var t2: int; + var s0: int; + var s1: int; + var ch: int; + var maj: int; + var w16: int; + + s1 = ror32(ctx.e, 6) ^ ror32(ctx.e, 11) ^ ror32(ctx.e, 25); + ch = (ctx.e & ctx.f) ^ ((~ctx.e) & ctx.g); + t1 = (ctx.h + s1 + ch + k + w[0]) & (-1 >> 32); + s0 = ror32(ctx.a, 2) ^ ror32(ctx.a, 13) ^ ror32(ctx.a, 22); + maj = (ctx.a & ctx.b) ^ (ctx.a & ctx.c) ^ (ctx.b & ctx.c); + t2 = (s0 + maj) & (-1 >> 32); + + s0 = ror32(w[16 - 15], 7) + ^ ror32(w[16 - 15], 18) + ^ (w[16 - 15] >> 3); + s1 = ror32(w[16 - 2], 17) + ^ ror32(w[16 - 2], 19) + ^ (w[16 - 2] >> 10); + w16 = (w[16 - 16] + s0 + w[16 - 7] + s1) & (-1 >> 32); + + w[0] = w[1]; + w[1] = w[2]; + w[2] = w[3]; + w[3] = w[4]; + w[4] = w[5]; + w[5] = w[6]; + w[6] = w[7]; + w[7] = w[8]; + w[8] = w[9]; + w[9] = w[10]; + w[10] = w[11]; + w[11] = w[12]; + w[12] = w[13]; + w[13] = w[14]; + w[14] = w[15]; + w[15] = w16; + + ctx.h = ctx.g; + ctx.g = ctx.f; + ctx.f = ctx.e; + ctx.e = (ctx.d + t1) & (-1 >> 32); + ctx.d = ctx.c; + ctx.c = ctx.b; + ctx.b = ctx.a; + ctx.a = (t1 + t2) & (-1 >> 32); +} + +sha256_rounds(ctx: *sha256_ctx, block: *byte) { + var _w: sha256_w; + var w: *int; + var r: sha256_ctx; + w = &_w.w0; + + r.a = ctx.a; + r.b = ctx.b; + r.c = ctx.c; + r.d = ctx.d; + r.e = ctx.e; + r.f = ctx.f; + r.g = ctx.g; + r.h = ctx.h; + + w[0] = (block[0]:int << 24) + | (block[1]:int << 16) + | (block[2]:int << 8) + | block[3]:int; + w[1] = (block[4]:int << 24) + | (block[5]:int << 16) + | (block[6]:int << 8) + | block[7]:int; + w[2] = (block[8]:int << 24) + | (block[9]:int << 16) + | (block[10]:int << 8) + | block[11]:int; + w[3] = (block[12]:int << 24) + | (block[13]:int << 16) + | (block[14]:int << 8) + | block[15]:int; + w[4] = (block[16]:int << 24) + | (block[17]:int << 16) + | (block[18]:int << 8) + | block[19]:int; + w[5] = (block[20]:int << 24) + | (block[21]:int << 16) + | (block[22]:int << 8) + | block[23]:int; + w[6] = (block[24]:int << 24) + | (block[25]:int << 16) + | (block[26]:int << 8) + | block[27]:int; + w[7] = (block[28]:int << 24) + | (block[29]:int << 16) + | (block[30]:int << 8) + | block[31]:int; + w[8] = (block[32]:int << 24) + | (block[33]:int << 16) + | (block[34]:int << 8) + | block[35]:int; + w[9] = (block[36]:int << 24) + | (block[37]:int << 16) + | (block[38]:int << 8) + | block[39]:int; + w[10] = (block[40]:int << 24) + | (block[41]:int << 16) + | (block[42]:int << 8) + | block[43]:int; + w[11] = (block[44]:int << 24) + | (block[45]:int << 16) + | (block[46]:int << 8) + | block[47]:int; + w[12] = (block[48]:int << 24) + | (block[49]:int << 16) + | (block[50]:int << 8) + | block[51]:int; + w[13] = (block[52]:int << 24) + | (block[53]:int << 16) + | (block[54]:int << 8) + | block[55]:int; + w[14] = (block[56]:int << 24) + | (block[57]:int << 16) + | (block[58]:int << 8) + | block[59]:int; + w[15] = (block[60]:int << 24) + | (block[61]:int << 16) + | (block[62]:int << 8) + | block[63]:int; + + sha256_round(&r, w, (0x428a << 16) | 0x2f98); + sha256_round(&r, w, (0x7137 << 16) | 0x4491); + sha256_round(&r, w, (0xb5c0 << 16) | 0xfbcf); + sha256_round(&r, w, (0xe9b5 << 16) | 0xdba5); + sha256_round(&r, w, (0x3956 << 16) | 0xc25b); + sha256_round(&r, w, (0x59f1 << 16) | 0x11f1); + sha256_round(&r, w, (0x923f << 16) | 0x82a4); + sha256_round(&r, w, (0xab1c << 16) | 0x5ed5); + sha256_round(&r, w, (0xd807 << 16) | 0xaa98); + sha256_round(&r, w, (0x1283 << 16) | 0x5b01); + sha256_round(&r, w, (0x2431 << 16) | 0x85be); + sha256_round(&r, w, (0x550c << 16) | 0x7dc3); + sha256_round(&r, w, (0x72be << 16) | 0x5d74); + sha256_round(&r, w, (0x80de << 16) | 0xb1fe); + sha256_round(&r, w, (0x9bdc << 16) | 0x06a7); + sha256_round(&r, w, (0xc19b << 16) | 0xf174); + sha256_round(&r, w, (0xe49b << 16) | 0x69c1); + sha256_round(&r, w, (0xefbe << 16) | 0x4786); + sha256_round(&r, w, (0x0fc1 << 16) | 0x9dc6); + sha256_round(&r, w, (0x240c << 16) | 0xa1cc); + sha256_round(&r, w, (0x2de9 << 16) | 0x2c6f); + sha256_round(&r, w, (0x4a74 << 16) | 0x84aa); + sha256_round(&r, w, (0x5cb0 << 16) | 0xa9dc); + sha256_round(&r, w, (0x76f9 << 16) | 0x88da); + sha256_round(&r, w, (0x983e << 16) | 0x5152); + sha256_round(&r, w, (0xa831 << 16) | 0xc66d); + sha256_round(&r, w, (0xb003 << 16) | 0x27c8); + sha256_round(&r, w, (0xbf59 << 16) | 0x7fc7); + sha256_round(&r, w, (0xc6e0 << 16) | 0x0bf3); + sha256_round(&r, w, (0xd5a7 << 16) | 0x9147); + sha256_round(&r, w, (0x06ca << 16) | 0x6351); + sha256_round(&r, w, (0x1429 << 16) | 0x2967); + sha256_round(&r, w, (0x27b7 << 16) | 0x0a85); + sha256_round(&r, w, (0x2e1b << 16) | 0x2138); + sha256_round(&r, w, (0x4d2c << 16) | 0x6dfc); + sha256_round(&r, w, (0x5338 << 16) | 0x0d13); + sha256_round(&r, w, (0x650a << 16) | 0x7354); + sha256_round(&r, w, (0x766a << 16) | 0x0abb); + sha256_round(&r, w, (0x81c2 << 16) | 0xc92e); + sha256_round(&r, w, (0x9272 << 16) | 0x2c85); + sha256_round(&r, w, (0xa2bf << 16) | 0xe8a1); + sha256_round(&r, w, (0xa81a << 16) | 0x664b); + sha256_round(&r, w, (0xc24b << 16) | 0x8b70); + sha256_round(&r, w, (0xc76c << 16) | 0x51a3); + sha256_round(&r, w, (0xd192 << 16) | 0xe819); + sha256_round(&r, w, (0xd699 << 16) | 0x0624); + sha256_round(&r, w, (0xf40e << 16) | 0x3585); + sha256_round(&r, w, (0x106a << 16) | 0xa070); + sha256_round(&r, w, (0x19a4 << 16) | 0xc116); + sha256_round(&r, w, (0x1e37 << 16) | 0x6c08); + sha256_round(&r, w, (0x2748 << 16) | 0x774c); + sha256_round(&r, w, (0x34b0 << 16) | 0xbcb5); + sha256_round(&r, w, (0x391c << 16) | 0x0cb3); + sha256_round(&r, w, (0x4ed8 << 16) | 0xaa4a); + sha256_round(&r, w, (0x5b9c << 16) | 0xca4f); + sha256_round(&r, w, (0x682e << 16) | 0x6ff3); + sha256_round(&r, w, (0x748f << 16) | 0x82ee); + sha256_round(&r, w, (0x78a5 << 16) | 0x636f); + sha256_round(&r, w, (0x84c8 << 16) | 0x7814); + sha256_round(&r, w, (0x8cc7 << 16) | 0x0208); + sha256_round(&r, w, (0x90be << 16) | 0xfffa); + sha256_round(&r, w, (0xa450 << 16) | 0x6ceb); + sha256_round(&r, w, (0xbef9 << 16) | 0xa3f7); + sha256_round(&r, w, (0xc671 << 16) | 0x78f2); + + ctx.a = (ctx.a + r.a) & (-1 >> 32); + ctx.b = (ctx.b + r.b) & (-1 >> 32); + ctx.c = (ctx.c + r.c) & (-1 >> 32); + ctx.d = (ctx.d + r.d) & (-1 >> 32); + ctx.e = (ctx.e + r.e) & (-1 >> 32); + ctx.f = (ctx.f + r.f) & (-1 >> 32); + ctx.g = (ctx.g + r.g) & (-1 >> 32); + ctx.h = (ctx.h + r.h) & (-1 >> 32); +} + +sha256_finish(ctx: *sha256_ctx, nblocks: int, data: *byte, len: int) { + var _final: sha256_ctx; + var final: *byte; + var pad: int; + var i: int; + + final = (&_final):*byte; + + pad = nblocks * 512; + + loop { + if len < 64 { + break; + } + + sha256_rounds(ctx, data); + + data = &data[64]; + len = len - 64; + pad = pad + 512; + } + + pad = pad + len * 8; + + i = 0; + loop { + if i == len { + break; + } + + final[i] = data[i]; + + i = i + 1; + } + + final[i] = 0x80:byte; + i = i + 1; + + loop { + if i == 64 { + break; + } + + final[i] = 0:byte; + + i = i + 1; + } + + if len + 9 > 64 { + sha256_rounds(ctx, final); + + i = 0; + loop { + if i == 64 { + break; + } + + final[i] = 0:byte; + + i = i + 1; + } + } + + final[56] = (pad >> 56):byte; + final[57] = (pad >> 48):byte; + final[58] = (pad >> 40):byte; + final[59] = (pad >> 32):byte; + final[60] = (pad >> 24):byte; + final[61] = (pad >> 16):byte; + final[62] = (pad >> 8):byte; + final[63] = pad:byte; + + sha256_rounds(ctx, final); +} + +sha256_digest(digest: *byte, ctx: *sha256_ctx) { + digest[0] = (ctx.a >> 24):byte; + digest[1] = (ctx.a >> 16):byte; + digest[2] = (ctx.a >> 8):byte; + digest[3] = ctx.a:byte; + digest[4] = (ctx.b >> 24):byte; + digest[5] = (ctx.b >> 16):byte; + digest[6] = (ctx.b >> 8):byte; + digest[7] = ctx.b:byte; + digest[8] = (ctx.c >> 24):byte; + digest[9] = (ctx.c >> 16):byte; + digest[10] = (ctx.c >> 8):byte; + digest[11] = ctx.c:byte; + digest[12] = (ctx.d >> 24):byte; + digest[13] = (ctx.d >> 16):byte; + digest[14] = (ctx.d >> 8):byte; + digest[15] = ctx.d:byte; + digest[16] = (ctx.e >> 24):byte; + digest[17] = (ctx.e >> 16):byte; + digest[18] = (ctx.e >> 8):byte; + digest[19] = ctx.e:byte; + digest[20] = (ctx.f >> 24):byte; + digest[21] = (ctx.f >> 16):byte; + digest[22] = (ctx.f >> 8):byte; + digest[23] = ctx.f:byte; + digest[24] = (ctx.g >> 24):byte; + digest[25] = (ctx.g >> 16):byte; + digest[26] = (ctx.g >> 8):byte; + digest[27] = ctx.g:byte; + digest[28] = (ctx.h >> 24):byte; + digest[29] = (ctx.h >> 16):byte; + digest[30] = (ctx.h >> 8):byte; + digest[31] = ctx.h:byte; +} + +sha256(digest: *byte, data: *byte, dlen: int) { + var ctx: sha256_ctx; + sha256_init(&ctx); + sha256_finish(&ctx, 0, data, dlen); + sha256_digest(digest, &ctx); +} + +sha256_hmac(mac: *byte, key: *byte, klen: int, data: *byte, dlen: int) { + var _digest: _sha256_digest; + var digest: *byte; + var _ipad: sha256_ctx; + var ipad: *byte; + var _opad: sha256_ctx; + var opad: *byte; + var ctx: sha256_ctx; + var i: int; + + digest = (&_digest):*byte; + ipad = (&_ipad):*byte; + opad = (&_opad):*byte; + + i = 0; + loop { + if i == 64 { + return; + } + + digest[i] = 0: byte; + + i = i + 1; + } + + if (klen <= 64) { + i = 0; + loop { + if i == klen { + break; + } + + digest[i] = key[i]; + + i = i + 1; + } + } else { + sha256(digest, key, klen); + } + + i = 0; + loop { + if i == 64 { + return; + } + + ipad[i] = digest[i] ^ (0x36:byte); + opad[i] = digest[i] ^ (0x5c:byte); + + i = i + 1; + } + + sha256_init(&ctx); + sha256_rounds(&ctx, ipad); + sha256_finish(&ctx, 1, data, dlen); + sha256_digest(digest, &ctx); + + sha256_init(&ctx); + sha256_rounds(&ctx, opad); + sha256_finish(&ctx, 1, digest, 32); + sha256_digest(mac, &ctx); +} diff --git a/sha256_test.c b/sha256_test.c @@ -0,0 +1,7 @@ +main(argc: int, argv: **byte, envp: **byte) { + var d: _sha256_digest; + var digest: *byte; + digest = (&d):*byte; + sha256(digest, argv[1], strlen(argv[1])); + fdxxd(1, digest, 32); +}