#define sha1_init nettle_sha1_init
#define sha1_update nettle_sha1_update
#define sha1_digest nettle_sha1_digest
+#define sha224_init nettle_sha224_init
+#define sha224_digest nettle_sha224_digest
#define sha256_init nettle_sha256_init
#define sha256_update nettle_sha256_update
#define sha256_digest nettle_sha256_digest
void
_nettle_sha256_compress(uint32_t *state, const uint8_t *data, const uint32_t *k);
+
+/* SHA224, a truncated SHA256 with different initial state. */
+
+#define SHA224_DIGEST_SIZE 28
+#define SHA224_DATA_SIZE SHA256_DATA_SIZE
+#define sha224_ctx sha256_ctx
+
+void
+sha224_init(struct sha256_ctx *ctx);
+
+#define sha224_update nettle_sha256_update
+
+void
+sha224_digest(struct sha256_ctx *ctx,
+ unsigned length,
+ uint8_t *digest);
+
+
/* SHA512 */
#define SHA512_DIGEST_SIZE 64
void
_nettle_sha512_compress(uint64_t *state, const uint8_t *data, const uint64_t *k);
-/* SHA384. */
-/* This is the same algorithm as SHA512, but with different initial
- state and truncated output. */
+
+/* SHA384, a truncated SHA512 with different initial state. */
#define SHA384_DIGEST_SIZE 48
#define SHA384_DATA_SIZE SHA512_DATA_SIZE
#include "sha.h"
#include "macros.h"
+#include "nettle-write.h"
/* Generated by the shadata program. */
static const uint32_t
unsigned length,
uint8_t *digest)
{
- unsigned i;
- unsigned words;
- unsigned leftover;
-
assert(length <= SHA256_DIGEST_SIZE);
sha256_final(ctx);
+ _nettle_write_be32(length, digest, ctx->state);
+ sha256_init(ctx);
+}
+
+/* sha224 variant. FIXME: Move to seperate file? */
+
+void
+sha224_init(struct sha256_ctx *ctx)
+{
+ /* Initial values. I's unclear how they are chosen. */
+ static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+ {
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
+ };
+
+ memcpy(ctx->state, H0, sizeof(H0));
+
+ /* Initialize bit count */
+ ctx->count_low = ctx->count_high = 0;
- words = length / 4;
- leftover = length % 4;
+ /* Initialize buffer */
+ ctx->index = 0;
+}
- for (i = 0; i < words; i++, digest += 4)
- WRITE_UINT32(digest, ctx->state[i]);
+void
+sha224_digest(struct sha256_ctx *ctx,
+ unsigned length,
+ uint8_t *digest)
+{
+ assert(length <= SHA224_DIGEST_SIZE);
- if (leftover)
- {
- uint32_t word;
- unsigned j = leftover;
-
- assert(i < _SHA256_DIGEST_LENGTH);
-
- word = ctx->state[i];
-
- switch (leftover)
- {
- default:
- abort();
- case 3:
- digest[--j] = (word >> 8) & 0xff;
- /* Fall through */
- case 2:
- digest[--j] = (word >> 16) & 0xff;
- /* Fall through */
- case 1:
- digest[--j] = (word >> 24) & 0xff;
- }
- }
- sha256_init(ctx);
+ sha256_final(ctx);
+ _nettle_write_be32(length, digest, ctx->state);
+ sha224_init(ctx);
}