commit 19a555939630998634e929b779ac915593859f36
parent bba729146433c34115f295fd31bbab9a5e816e5c
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 11 May 2026 18:16:30 -0700
extract sha256 (codesign)
Diffstat:
3 files changed, 133 insertions(+), 113 deletions(-)
diff --git a/src/core/sha256.c b/src/core/sha256.c
@@ -0,0 +1,112 @@
+#include <string.h>
+
+#include "core/sha256.h"
+
+static const u32 SHA256_K[64] = {
+ 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu,
+ 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u,
+ 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u,
+ 0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu,
+ 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u,
+ 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u,
+ 0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu,
+ 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
+ 0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u,
+ 0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u, 0x1e376c08u,
+ 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu,
+ 0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u,
+ 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u};
+
+static u32 sha256_rotr32(u32 v, u32 n) {
+ return (v >> n) | (v << (32 - n));
+}
+
+void sha256_init(Sha256* s) {
+ s->h[0] = 0x6a09e667u;
+ s->h[1] = 0xbb67ae85u;
+ s->h[2] = 0x3c6ef372u;
+ s->h[3] = 0xa54ff53au;
+ s->h[4] = 0x510e527fu;
+ s->h[5] = 0x9b05688cu;
+ s->h[6] = 0x1f83d9abu;
+ s->h[7] = 0x5be0cd19u;
+ s->buflen = 0;
+ s->total = 0;
+}
+
+static void sha256_block(Sha256* s, const u8* p) {
+ u32 w[64];
+ for (u32 i = 0; i < 16; ++i)
+ w[i] = ((u32)p[i * 4] << 24) | ((u32)p[i * 4 + 1] << 16) |
+ ((u32)p[i * 4 + 2] << 8) | (u32)p[i * 4 + 3];
+ for (u32 i = 16; i < 64; ++i) {
+ u32 s0 = sha256_rotr32(w[i - 15], 7) ^
+ sha256_rotr32(w[i - 15], 18) ^ (w[i - 15] >> 3);
+ u32 s1 = sha256_rotr32(w[i - 2], 17) ^
+ sha256_rotr32(w[i - 2], 19) ^ (w[i - 2] >> 10);
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1;
+ }
+ u32 a = s->h[0], b = s->h[1], cc = s->h[2], d = s->h[3];
+ u32 e = s->h[4], f = s->h[5], g = s->h[6], hh = s->h[7];
+ for (u32 i = 0; i < 64; ++i) {
+ u32 S1 = sha256_rotr32(e, 6) ^ sha256_rotr32(e, 11) ^
+ sha256_rotr32(e, 25);
+ u32 ch = (e & f) ^ ((~e) & g);
+ u32 t1 = hh + S1 + ch + SHA256_K[i] + w[i];
+ u32 S0 = sha256_rotr32(a, 2) ^ sha256_rotr32(a, 13) ^
+ sha256_rotr32(a, 22);
+ u32 mj = (a & b) ^ (a & cc) ^ (b & cc);
+ u32 t2 = S0 + mj;
+ hh = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = cc;
+ cc = b;
+ b = a;
+ a = t1 + t2;
+ }
+ s->h[0] += a;
+ s->h[1] += b;
+ s->h[2] += cc;
+ s->h[3] += d;
+ s->h[4] += e;
+ s->h[5] += f;
+ s->h[6] += g;
+ s->h[7] += hh;
+}
+
+void sha256_update(Sha256* s, const u8* data, u32 n) {
+ s->total += n;
+ while (n) {
+ u32 take = 64u - s->buflen;
+ if (take > n) take = n;
+ memcpy(s->buf + s->buflen, data, take);
+ s->buflen += take;
+ data += take;
+ n -= take;
+ if (s->buflen == 64) {
+ sha256_block(s, s->buf);
+ s->buflen = 0;
+ }
+ }
+}
+
+void sha256_final(Sha256* s, u8 out[SHA256_DIGEST_LEN]) {
+ u64 bits = s->total * 8u;
+ u8 pad1 = 0x80;
+ sha256_update(s, &pad1, 1);
+ while (s->buflen != 56) {
+ u8 z = 0;
+ sha256_update(s, &z, 1);
+ }
+ u8 lenbe[8];
+ for (u32 i = 0; i < 8; ++i) lenbe[7 - i] = (u8)(bits >> (i * 8));
+ sha256_update(s, lenbe, 8);
+ for (u32 i = 0; i < 8; ++i) {
+ out[i * 4 + 0] = (u8)(s->h[i] >> 24);
+ out[i * 4 + 1] = (u8)(s->h[i] >> 16);
+ out[i * 4 + 2] = (u8)(s->h[i] >> 8);
+ out[i * 4 + 3] = (u8)(s->h[i]);
+ }
+}
diff --git a/src/core/sha256.h b/src/core/sha256.h
@@ -0,0 +1,19 @@
+#ifndef CFREE_SHA256_H
+#define CFREE_SHA256_H
+
+#include "core/core.h"
+
+#define SHA256_DIGEST_LEN 32u
+
+typedef struct Sha256 {
+ u32 h[8];
+ u8 buf[64];
+ u32 buflen;
+ u64 total;
+} Sha256;
+
+void sha256_init(Sha256* s);
+void sha256_update(Sha256* s, const u8* data, u32 n);
+void sha256_final(Sha256* s, u8 out[SHA256_DIGEST_LEN]);
+
+#endif
diff --git a/src/link/link_macho.c b/src/link/link_macho.c
@@ -43,6 +43,7 @@
#include "core/bytes.h"
#include "core/heap.h"
#include "core/pool.h"
+#include "core/sha256.h"
#include "core/util.h"
#include "core/vec.h"
#include "link/link.h"
@@ -75,7 +76,7 @@ static SrcLoc no_loc(void) {
#define CS_MAGIC_CODEDIRECTORY 0xfade0c02u
#define CSSLOT_CODEDIRECTORY 0u
#define CS_HASHTYPE_SHA256 2u
-#define CS_SHA256_LEN 32u
+#define CS_SHA256_LEN SHA256_DIGEST_LEN
#define CS_PAGE_SIZE_LOG2 12u
#define CS_EXECSEG_MAIN_BINARY 1u
@@ -2082,118 +2083,6 @@ static void layout_linkedit(MCtx* x) {
* blob's own offset in the file (the hash range stops just before
* codeLimit). */
-/* Tiny SHA-256 implementation. */
-
-static const u32 SHA256_K[64] = {
- 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu,
- 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u,
- 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u,
- 0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu,
- 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u,
- 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u,
- 0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu,
- 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
- 0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u,
- 0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u, 0x1e376c08u,
- 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu,
- 0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u,
- 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u};
-
-static u32 rotr32(u32 v, u32 n) { return (v >> n) | (v << (32 - n)); }
-
-typedef struct Sha256 {
- u32 h[8];
- u8 buf[64];
- u32 buflen;
- u64 total;
-} Sha256;
-
-static void sha256_init(Sha256* s) {
- s->h[0] = 0x6a09e667u;
- s->h[1] = 0xbb67ae85u;
- s->h[2] = 0x3c6ef372u;
- s->h[3] = 0xa54ff53au;
- s->h[4] = 0x510e527fu;
- s->h[5] = 0x9b05688cu;
- s->h[6] = 0x1f83d9abu;
- s->h[7] = 0x5be0cd19u;
- s->buflen = 0;
- s->total = 0;
-}
-
-static void sha256_block(Sha256* s, const u8* p) {
- u32 w[64];
- for (u32 i = 0; i < 16; ++i)
- w[i] = ((u32)p[i * 4] << 24) | ((u32)p[i * 4 + 1] << 16) |
- ((u32)p[i * 4 + 2] << 8) | (u32)p[i * 4 + 3];
- for (u32 i = 16; i < 64; ++i) {
- u32 s0 = rotr32(w[i - 15], 7) ^ rotr32(w[i - 15], 18) ^ (w[i - 15] >> 3);
- u32 s1 = rotr32(w[i - 2], 17) ^ rotr32(w[i - 2], 19) ^ (w[i - 2] >> 10);
- w[i] = w[i - 16] + s0 + w[i - 7] + s1;
- }
- u32 a = s->h[0], b = s->h[1], cc = s->h[2], d = s->h[3];
- u32 e = s->h[4], f = s->h[5], g = s->h[6], hh = s->h[7];
- for (u32 i = 0; i < 64; ++i) {
- u32 S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);
- u32 ch = (e & f) ^ ((~e) & g);
- u32 t1 = hh + S1 + ch + SHA256_K[i] + w[i];
- u32 S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);
- u32 mj = (a & b) ^ (a & cc) ^ (b & cc);
- u32 t2 = S0 + mj;
- hh = g;
- g = f;
- f = e;
- e = d + t1;
- d = cc;
- cc = b;
- b = a;
- a = t1 + t2;
- }
- s->h[0] += a;
- s->h[1] += b;
- s->h[2] += cc;
- s->h[3] += d;
- s->h[4] += e;
- s->h[5] += f;
- s->h[6] += g;
- s->h[7] += hh;
-}
-
-static void sha256_update(Sha256* s, const u8* data, u32 n) {
- s->total += n;
- while (n) {
- u32 take = 64u - s->buflen;
- if (take > n) take = n;
- memcpy(s->buf + s->buflen, data, take);
- s->buflen += take;
- data += take;
- n -= take;
- if (s->buflen == 64) {
- sha256_block(s, s->buf);
- s->buflen = 0;
- }
- }
-}
-
-static void sha256_final(Sha256* s, u8 out[32]) {
- u64 bits = s->total * 8u;
- u8 pad1 = 0x80;
- sha256_update(s, &pad1, 1);
- while (s->buflen != 56) {
- u8 z = 0;
- sha256_update(s, &z, 1);
- }
- u8 lenbe[8];
- for (u32 i = 0; i < 8; ++i) lenbe[7 - i] = (u8)(bits >> (i * 8));
- sha256_update(s, lenbe, 8);
- for (u32 i = 0; i < 8; ++i) {
- out[i * 4 + 0] = (u8)(s->h[i] >> 24);
- out[i * 4 + 1] = (u8)(s->h[i] >> 16);
- out[i * 4 + 2] = (u8)(s->h[i] >> 8);
- out[i * 4 + 3] = (u8)(s->h[i]);
- }
-}
-
static void wr_u64_be(u8* p, u64 v) {
for (u32 i = 0; i < 8; ++i) p[7 - i] = (u8)(v >> (i * 8));
}