summaryrefslogtreecommitdiff
path: root/src/libstdcrypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstdcrypto')
-rw-r--r--src/libstdcrypto/INCLUDE5
-rw-r--r--src/libstdcrypto/Makefile7
-rw-r--r--src/libstdcrypto/md5-internal.h11
-rw-r--r--src/libstdcrypto/md5_final.c30
-rw-r--r--src/libstdcrypto/md5_init.c13
-rw-r--r--src/libstdcrypto/md5_transform.c91
-rw-r--r--src/libstdcrypto/md5_update.c37
-rw-r--r--src/libstdcrypto/rc4.c20
-rw-r--r--src/libstdcrypto/rc4_init.c26
-rw-r--r--src/libstdcrypto/sha1-internal.h12
-rw-r--r--src/libstdcrypto/sha1_feed.c24
-rw-r--r--src/libstdcrypto/sha1_final.c18
-rw-r--r--src/libstdcrypto/sha1_init.c16
-rw-r--r--src/libstdcrypto/sha1_transform.c42
-rw-r--r--src/libstdcrypto/sha1_update.c10
-rw-r--r--src/libstdcrypto/sha256-internal.h12
-rw-r--r--src/libstdcrypto/sha256_feed.c23
-rw-r--r--src/libstdcrypto/sha256_final.c31
-rw-r--r--src/libstdcrypto/sha256_init.c9
-rw-r--r--src/libstdcrypto/sha256_transform.c53
-rw-r--r--src/libstdcrypto/sha256_update.c10
21 files changed, 500 insertions, 0 deletions
diff --git a/src/libstdcrypto/INCLUDE b/src/libstdcrypto/INCLUDE
new file mode 100644
index 0000000..563254f
--- /dev/null
+++ b/src/libstdcrypto/INCLUDE
@@ -0,0 +1,5 @@
+rc4.h
+md5.h
+sha1.h
+sha256.h
+stdcrypto.h
diff --git a/src/libstdcrypto/Makefile b/src/libstdcrypto/Makefile
new file mode 100644
index 0000000..8c0d22f
--- /dev/null
+++ b/src/libstdcrypto/Makefile
@@ -0,0 +1,7 @@
+it: EXPORT- .done
+
+EXPORT-: gen-EXPORT
+ exec ./gen-EXPORT > EXPORT-
+
+.done: gen-Makefile
+ ./gen-Makefile > Makefile.real && make -f Makefile.real && : > .done
diff --git a/src/libstdcrypto/md5-internal.h b/src/libstdcrypto/md5-internal.h
new file mode 100644
index 0000000..374528a
--- /dev/null
+++ b/src/libstdcrypto/md5-internal.h
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#ifndef MD5_INTERNAL_H
+#define MD5_INTERNAL_H
+
+#include <skalibs/uint32.h>
+#include <skalibs/md5.h>
+
+extern void md5_transform (uint32 * /* 4 uint32s */, uint32 const * /* 16 uint32s */) ;
+
+#endif
diff --git a/src/libstdcrypto/md5_final.c b/src/libstdcrypto/md5_final.c
new file mode 100644
index 0000000..834d57c
--- /dev/null
+++ b/src/libstdcrypto/md5_final.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/md5.h>
+#include "md5-internal.h"
+
+void md5_final (MD5Schedule_ref ctx, char *digest /* 16 chars */)
+{
+ register unsigned int count = (ctx->bits[0] >> 3) & 0x3F ;
+ register unsigned char *p = ctx->in + count ;
+ *p++ = 0x80;
+ count = 63 - count ;
+ if (count < 8)
+ {
+ byte_zero(p, count) ;
+ uint32_little_endian((char *)ctx->in, 16) ;
+ md5_transform(ctx->buf, (uint32 *)ctx->in) ;
+ byte_zero(ctx->in, 56) ;
+ }
+ else byte_zero(p, count - 8) ;
+ uint32_little_endian((char *)ctx->in, 14) ;
+
+ byte_copy(ctx->in + 56, 4, (char *)&ctx->bits[0]) ;
+ byte_copy(ctx->in + 60, 4, (char *)&ctx->bits[1]) ;
+
+ md5_transform(ctx->buf, (uint32 *)ctx->in) ;
+ uint32_little_endian((char *)ctx->buf, 4) ;
+ byte_copy(digest, 16, (char *)ctx->buf) ;
+}
diff --git a/src/libstdcrypto/md5_init.c b/src/libstdcrypto/md5_init.c
new file mode 100644
index 0000000..cb2f611
--- /dev/null
+++ b/src/libstdcrypto/md5_init.c
@@ -0,0 +1,13 @@
+/* ISC license. */
+
+#include <skalibs/md5.h>
+
+void md5_init (MD5Schedule_ref ctx)
+{
+ ctx->buf[0] = 0x67452301UL ;
+ ctx->buf[1] = 0xefcdab89UL ;
+ ctx->buf[2] = 0x98badcfeUL ;
+ ctx->buf[3] = 0x10325476UL ;
+ ctx->bits[0] = 0 ;
+ ctx->bits[1] = 0 ;
+}
diff --git a/src/libstdcrypto/md5_transform.c b/src/libstdcrypto/md5_transform.c
new file mode 100644
index 0000000..2449b58
--- /dev/null
+++ b/src/libstdcrypto/md5_transform.c
@@ -0,0 +1,91 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include "md5-internal.h"
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+void md5_transform (uint32 *buf /* 4 uint32s */, uint32 const *in /* 16 uint32s */)
+{
+ register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3] ;
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7) ;
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12) ;
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17) ;
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22) ;
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7) ;
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12) ;
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17) ;
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22) ;
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7) ;
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12) ;
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17) ;
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22) ;
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7) ;
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12) ;
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17) ;
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22) ;
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5) ;
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9) ;
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14) ;
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20) ;
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5) ;
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9) ;
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14) ;
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20) ;
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5) ;
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9) ;
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14) ;
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20) ;
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5) ;
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9) ;
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14) ;
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20) ;
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4) ;
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11) ;
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16) ;
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23) ;
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4) ;
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11) ;
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16) ;
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23) ;
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4) ;
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11) ;
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16) ;
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23) ;
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4) ;
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11) ;
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16) ;
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23) ;
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6) ;
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10) ;
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15) ;
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21) ;
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6) ;
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10) ;
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15) ;
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21) ;
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6) ;
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10) ;
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15) ;
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21) ;
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6) ;
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10) ;
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15) ;
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21) ;
+
+ buf[0] += a ;
+ buf[1] += b ;
+ buf[2] += c ;
+ buf[3] += d ;
+}
diff --git a/src/libstdcrypto/md5_update.c b/src/libstdcrypto/md5_update.c
new file mode 100644
index 0000000..63fdea3
--- /dev/null
+++ b/src/libstdcrypto/md5_update.c
@@ -0,0 +1,37 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/md5.h>
+#include "md5-internal.h"
+
+void md5_update (MD5Schedule_ref ctx, char const *s, unsigned int len)
+{
+ register uint32 t = ctx->bits[0] ;
+ if ((ctx->bits[0] = t + (len << 3)) < t)
+ ctx->bits[1]++ ;
+ ctx->bits[1] += len >> 29 ;
+ t = (t >> 3) & 0x3f ;
+ if (t)
+ {
+ unsigned char *p = ctx->in + t ;
+ t = 64 - t ;
+ if (len < t)
+ {
+ byte_copy((char *)p, len, s) ;
+ return ;
+ }
+ byte_copy((char *)p, t, s) ;
+ uint32_little_endian((char *)ctx->in, 16) ;
+ md5_transform(ctx->buf, (uint32 *)ctx->in) ;
+ s += t ; len -= t ;
+ }
+ while (len >= 64)
+ {
+ byte_copy((char *)ctx->in, 64, s) ;
+ uint32_little_endian((char *)ctx->in, 16) ;
+ md5_transform(ctx->buf, (uint32 *)ctx->in) ;
+ s += 64 ; len -= 64 ;
+ }
+ byte_copy((char *)ctx->in, len, s) ;
+}
diff --git a/src/libstdcrypto/rc4.c b/src/libstdcrypto/rc4.c
new file mode 100644
index 0000000..7ead2c6
--- /dev/null
+++ b/src/libstdcrypto/rc4.c
@@ -0,0 +1,20 @@
+/* ISC license. */
+/* Thanks to Thomas Pornin <pornin@bolet.org> */
+
+#include <skalibs/bytestr.h>
+#include <skalibs/rc4.h>
+
+void rc4 (RC4Schedule_ref r, char const *in, char *out, unsigned int n)
+{
+ register unsigned int i = 0 ;
+ for (; i < n ; i++)
+ {
+ register unsigned char t ;
+ r->x = T8(r->x + 1) ;
+ t = r->tab[r->x] ;
+ r->y = T8(r->y + t) ;
+ r->tab[r->x] = r->tab[r->y] ;
+ r->tab[r->y] = t ;
+ out[i] = (unsigned char)in[i] ^ T8(r->tab[r->x] + r->tab[r->y]) ;
+ }
+}
diff --git a/src/libstdcrypto/rc4_init.c b/src/libstdcrypto/rc4_init.c
new file mode 100644
index 0000000..d6f8c20
--- /dev/null
+++ b/src/libstdcrypto/rc4_init.c
@@ -0,0 +1,26 @@
+/* ISC license. */
+/* Thanks to Thomas Pornin <pornin@bolet.org> */
+
+#include <skalibs/bytestr.h>
+#include <skalibs/rc4.h>
+
+void rc4_init (RC4Schedule_ref r, char const *key, unsigned int ksize)
+{
+ register unsigned int i = 0, j = 0 ;
+ register unsigned char c = 0;
+
+ r->x = r->y = 0 ;
+ for (; i < 256 ; i++) r->tab[i] = i ;
+ for (i = 0 ; i < 256 ; i++)
+ {
+ unsigned char t = r->tab[i] ;
+ c = T8(c + (unsigned char)key[j] + t) ;
+ r->tab[i] = r->tab[c] ;
+ r->tab[c] = t ;
+ if (++j == ksize) j = 0 ;
+ }
+ {
+ char tmp[RC4_THROWAWAY] ;
+ rc4(r, tmp, tmp, RC4_THROWAWAY) ;
+ }
+}
diff --git a/src/libstdcrypto/sha1-internal.h b/src/libstdcrypto/sha1-internal.h
new file mode 100644
index 0000000..eae3947
--- /dev/null
+++ b/src/libstdcrypto/sha1-internal.h
@@ -0,0 +1,12 @@
+/* ISC license. */
+
+#ifndef SHA1_INTERNAL_H
+#define SHA1_INTERNAL_H
+
+#include <skalibs/uint32.h>
+#include <skalibs/sha1.h>
+
+extern void sha1_feed (SHA1Schedule_ref, unsigned char) ;
+extern void sha1_transform (uint32 * /* 5 uint32s */, uint32 const * /* 16 uint32s */) ;
+
+#endif
diff --git a/src/libstdcrypto/sha1_feed.c b/src/libstdcrypto/sha1_feed.c
new file mode 100644
index 0000000..208cebd
--- /dev/null
+++ b/src/libstdcrypto/sha1_feed.c
@@ -0,0 +1,24 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/sha1.h>
+#include "sha1-internal.h"
+
+void sha1_feed (SHA1Schedule_ref ctx, unsigned char inb)
+{
+ register uint32 tmp ;
+
+ ctx->in[ctx->b>>2] <<= 8 ;
+ ctx->in[ctx->b>>2] |= T8(inb) ;
+ if (++ctx->b >= 64)
+ {
+ register unsigned int i = 0 ;
+ sha1_transform(ctx->buf, ctx->in) ;
+ ctx->b = 0 ;
+ for (i = 0 ; i < 16 ; i++) ctx->in[i] = 0 ;
+ }
+ tmp = ctx->bits[0] ;
+ ctx->bits[0] += 8 ;
+ if (tmp > ctx->bits[0]) ctx->bits[1]++ ;
+}
diff --git a/src/libstdcrypto/sha1_final.c b/src/libstdcrypto/sha1_final.c
new file mode 100644
index 0000000..4af2efb
--- /dev/null
+++ b/src/libstdcrypto/sha1_final.c
@@ -0,0 +1,18 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <skalibs/sha1.h>
+#include "sha1-internal.h"
+
+void sha1_final (SHA1Schedule_ref ctx, char *digest)
+{
+ char pack[8] ;
+ register unsigned int i = 0 ;
+ uint32_pack_big(pack, ctx->bits[1]) ;
+ uint32_pack_big(pack+4, ctx->bits[0]) ;
+ sha1_feed(ctx, 0x80) ;
+ while (ctx->b != 56) sha1_feed(ctx, 0) ;
+ sha1_update(ctx, pack, 8) ;
+ for (; i < 5 ; i++)
+ uint32_pack_big(digest + (i<<2), ctx->buf[i]) ;
+}
diff --git a/src/libstdcrypto/sha1_init.c b/src/libstdcrypto/sha1_init.c
new file mode 100644
index 0000000..bdcb5fd
--- /dev/null
+++ b/src/libstdcrypto/sha1_init.c
@@ -0,0 +1,16 @@
+/* ISC license. */
+
+#include <skalibs/sha1.h>
+
+void sha1_init (SHA1Schedule_ref ctx)
+{
+ register unsigned int i = 0 ;
+ ctx->buf[0] = 0x67452301UL ;
+ ctx->buf[1] = 0xefcdab89UL ;
+ ctx->buf[2] = 0x98badcfeUL ;
+ ctx->buf[3] = 0x10325476UL ;
+ ctx->buf[4] = 0xc3d2e1f0UL ;
+ ctx->bits[0] = ctx->bits[1] = 0 ;
+ for (; i < 16 ; i++) ctx->in[i] = 0 ;
+ ctx->b = 0 ;
+}
diff --git a/src/libstdcrypto/sha1_transform.c b/src/libstdcrypto/sha1_transform.c
new file mode 100644
index 0000000..bd6e624
--- /dev/null
+++ b/src/libstdcrypto/sha1_transform.c
@@ -0,0 +1,42 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include "sha1-internal.h"
+
+#define F1(x, y, z) ((x & y) | ((~x) & z))
+#define F2(x, y, z) (x ^ y ^ z)
+#define F3(x, y, z) ((x & y) | (x & z) | (y & z))
+#define F4(x, y, z) (x ^ y ^ z)
+
+#define SHA1STEP(f, data) \
+{ \
+ register uint32 tmp = e + f(b, c, d) + data + ((a<<5) | (a>>27)); \
+ e = d ; \
+ d = c ; \
+ c = (b<<30) | (b>>2) ; \
+ b = a ; \
+ a = tmp ; \
+}
+
+void sha1_transform (uint32 *buf, uint32 const *in)
+{
+ register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3], e = buf[4] ;
+ uint32 w[80] ;
+ register unsigned int i = 0 ;
+
+ for (; i < 16 ; i++) w[i] = in[i] ;
+ for (; i < 80 ; i++)
+ {
+ w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16] ;
+ w[i] = (w[i]<<1) | (w[i]>>31) ;
+ }
+ for (i = 0 ; i < 20 ; i++)
+ SHA1STEP(F1, w[i] + 0x5a827999UL) ;
+ for (; i < 40 ; i++)
+ SHA1STEP(F2, w[i] + 0x6ed9eba1UL) ;
+ for (; i < 60 ; i++)
+ SHA1STEP(F3, w[i] + 0x8f1bbcdcUL) ;
+ for (; i < 80 ; i++)
+ SHA1STEP(F4, w[i] + 0xca62c1d6UL) ;
+ buf[0] += a ; buf[1] += b ; buf[2] += c ; buf[3] += d ; buf[4] += e ;
+}
diff --git a/src/libstdcrypto/sha1_update.c b/src/libstdcrypto/sha1_update.c
new file mode 100644
index 0000000..1b3c4de
--- /dev/null
+++ b/src/libstdcrypto/sha1_update.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/sha1.h>
+#include "sha1-internal.h"
+
+void sha1_update (SHA1Schedule_ref ctx, char const *buf, unsigned int len)
+{
+ register unsigned int i = 0 ;
+ for (; i < len ; i++) sha1_feed(ctx, (unsigned char)buf[i]) ;
+}
diff --git a/src/libstdcrypto/sha256-internal.h b/src/libstdcrypto/sha256-internal.h
new file mode 100644
index 0000000..377e6ef
--- /dev/null
+++ b/src/libstdcrypto/sha256-internal.h
@@ -0,0 +1,12 @@
+/* ISC license. */
+
+#ifndef SHA256_INTERNAL_H
+#define SHA256_INTERNAL_H
+
+#include <skalibs/uint32.h>
+#include <skalibs/sha256.h>
+
+extern void sha256_feed (SHA256Schedule_ref, unsigned char) ;
+extern void sha256_transform (uint32 *, uint32 const *) ;
+
+#endif
diff --git a/src/libstdcrypto/sha256_feed.c b/src/libstdcrypto/sha256_feed.c
new file mode 100644
index 0000000..5533d75
--- /dev/null
+++ b/src/libstdcrypto/sha256_feed.c
@@ -0,0 +1,23 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/sha256.h>
+#include "sha256-internal.h"
+
+void sha256_feed (SHA256Schedule_ref ctx, unsigned char inb)
+{
+ register uint32 tmp ;
+ ctx->in[ctx->b>>2] <<= 8 ;
+ ctx->in[ctx->b>>2] |= T8(inb) ;
+ if (++ctx->b >= 64)
+ {
+ register unsigned int i = 0 ;
+ sha256_transform(ctx->buf, ctx->in) ;
+ ctx->b = 0 ;
+ for (; i < 16 ; i++) ctx->in[i] = 0 ;
+ }
+ tmp = ctx->bits[0] ;
+ ctx->bits[0] += 8 ;
+ if (tmp > ctx->bits[0]) ctx->bits[1]++ ;
+}
diff --git a/src/libstdcrypto/sha256_final.c b/src/libstdcrypto/sha256_final.c
new file mode 100644
index 0000000..58b938a
--- /dev/null
+++ b/src/libstdcrypto/sha256_final.c
@@ -0,0 +1,31 @@
+/* ISC license. */
+
+#include <skalibs/bytestr.h>
+#include <skalibs/uint32.h>
+#include <skalibs/sha256.h>
+#include "sha256-internal.h"
+
+void sha256_final (SHA256Schedule_ref ctx, char *digest)
+{
+ register unsigned int i = 0 ;
+ register unsigned char *p = (unsigned char *)digest ;
+ uint32 bits[2] = { ctx->bits[0], ctx->bits[1] } ;
+
+ sha256_feed(ctx, 0x80) ;
+ while (ctx->b != 56) sha256_feed(ctx, 0) ;
+ sha256_feed(ctx, T8(bits[1]>>24)) ;
+ sha256_feed(ctx, T8(bits[1]>>16)) ;
+ sha256_feed(ctx, T8(bits[1]>>8)) ;
+ sha256_feed(ctx, T8(bits[1])) ;
+ sha256_feed(ctx, T8(bits[0]>>24)) ;
+ sha256_feed(ctx, T8(bits[0]>>16)) ;
+ sha256_feed(ctx, T8(bits[0]>>8)) ;
+ sha256_feed(ctx, T8(bits[0])) ;
+ for (; i < 8 ; i++)
+ {
+ *p++ = T8(ctx->buf[i]>>24) ;
+ *p++ = T8(ctx->buf[i]>>16) ;
+ *p++ = T8(ctx->buf[i]>>8) ;
+ *p++ = T8(ctx->buf[i]) ;
+ }
+}
diff --git a/src/libstdcrypto/sha256_init.c b/src/libstdcrypto/sha256_init.c
new file mode 100644
index 0000000..e8a9ae1
--- /dev/null
+++ b/src/libstdcrypto/sha256_init.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/sha256.h>
+
+void sha256_init (SHA256Schedule_ref ctx)
+{
+ SHA256Schedule empty = SHA256_INIT() ;
+ *ctx = empty ;
+}
diff --git a/src/libstdcrypto/sha256_transform.c b/src/libstdcrypto/sha256_transform.c
new file mode 100644
index 0000000..e61775c
--- /dev/null
+++ b/src/libstdcrypto/sha256_transform.c
@@ -0,0 +1,53 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include "sha256-internal.h"
+
+#define F1(x, y, z) ((x & y) | ((~x) & z))
+#define F2(x, y, z) ((x & y) | (x & z) | (y & z))
+
+#define ROTR(x,n) (((x)>>(n)) | ((x)<<(32-(n))))
+#define CAPITALSIGMA0(x) (ROTR(x,2)^ROTR(x,13)^ROTR(x,22))
+#define CAPITALSIGMA1(x) (ROTR(x,6)^ROTR(x,11)^ROTR(x,25))
+#define SMALLSIGMA0(x) (ROTR(x,7)^ROTR(x,18)^((x)>>3))
+#define SMALLSIGMA1(x) (ROTR(x,17)^ROTR(x,19)^((x)>>10))
+
+static uint32 const sha256_constants[64] =
+{
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+} ;
+
+void sha256_transform (uint32 *buf, uint32 const *in)
+{
+ uint32 w[64] ;
+ unsigned int i = 0 ;
+ register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3], e = buf[4], f = buf[5], g = buf[6], h = buf[7] ;
+
+ for (; i < 16 ; i++) w[i] = in[i] ;
+ for (; i < 64 ; i++)
+ w[i] = SMALLSIGMA1(w[i-2]) + w[i-7] + SMALLSIGMA0(w[i-15]) + w[i-16] ;
+ for (i = 0 ; i < 64 ; i++)
+ {
+ uint32 temp1 = h + CAPITALSIGMA1(e) + F1(e, f, g) + sha256_constants[i] + w[i] ;
+ uint32 temp2 = CAPITALSIGMA0(a) + F2(a, b, c) ;
+ h = g ; g = f ; f = e ; e = d + temp1 ;
+ d = c ; c = b ; b = a ; a = temp1 + temp2 ;
+ }
+ buf[0] += a ; buf[1] += b ; buf[2] += c ; buf[3] += d ;
+ buf[4] += e ; buf[5] += f ; buf[6] += g ; buf[7] += h ;
+}
diff --git a/src/libstdcrypto/sha256_update.c b/src/libstdcrypto/sha256_update.c
new file mode 100644
index 0000000..c87644e
--- /dev/null
+++ b/src/libstdcrypto/sha256_update.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/sha256.h>
+#include "sha256-internal.h"
+
+void sha256_update (SHA256Schedule_ref ctx, char const *buf, unsigned int len)
+{
+ register unsigned int i = 0 ;
+ for (; i < len ; i++) sha256_feed(ctx, (unsigned char)buf[i]) ;
+}