mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-01-30 23:02:18 +00:00
2a709f28fa
* 0day explit mitigation * Memory corruption prevention * Privilege escalation prevention * Buffer over flow prevention * File System corruption defense * Thread escape prevention This may very well be the most intensive inclusion to BrooklynR. This will not be part of an x86 suite nor it will be released as tool kit. The security core toolkit will remain part of kernel base.
107 lines
2.5 KiB
C
107 lines
2.5 KiB
C
/*
|
|
* sha1_base.h - core logic for SHA-1 implementations
|
|
*
|
|
* Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <crypto/internal/hash.h>
|
|
#include <crypto/sha.h>
|
|
#include <linux/crypto.h>
|
|
#include <linux/module.h>
|
|
|
|
#include <asm/unaligned.h>
|
|
|
|
typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks);
|
|
|
|
static inline int sha1_base_init(struct shash_desc *desc)
|
|
{
|
|
struct sha1_state *sctx = shash_desc_ctx(desc);
|
|
|
|
sctx->state[0] = SHA1_H0;
|
|
sctx->state[1] = SHA1_H1;
|
|
sctx->state[2] = SHA1_H2;
|
|
sctx->state[3] = SHA1_H3;
|
|
sctx->state[4] = SHA1_H4;
|
|
sctx->count = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int sha1_base_do_update(struct shash_desc *desc,
|
|
const u8 *data,
|
|
unsigned int len,
|
|
sha1_block_fn *block_fn)
|
|
{
|
|
struct sha1_state *sctx = shash_desc_ctx(desc);
|
|
unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
|
|
|
|
sctx->count += len;
|
|
|
|
if (unlikely((partial + len) >= SHA1_BLOCK_SIZE)) {
|
|
int blocks;
|
|
|
|
if (partial) {
|
|
int p = SHA1_BLOCK_SIZE - partial;
|
|
|
|
memcpy(sctx->buffer + partial, data, p);
|
|
data += p;
|
|
len -= p;
|
|
|
|
block_fn(sctx, sctx->buffer, 1);
|
|
}
|
|
|
|
blocks = len / SHA1_BLOCK_SIZE;
|
|
len %= SHA1_BLOCK_SIZE;
|
|
|
|
if (blocks) {
|
|
block_fn(sctx, data, blocks);
|
|
data += blocks * SHA1_BLOCK_SIZE;
|
|
}
|
|
partial = 0;
|
|
}
|
|
if (len)
|
|
memcpy(sctx->buffer + partial, data, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int sha1_base_do_finalize(struct shash_desc *desc,
|
|
sha1_block_fn *block_fn)
|
|
{
|
|
const int bit_offset = SHA1_BLOCK_SIZE - sizeof(__be64);
|
|
struct sha1_state *sctx = shash_desc_ctx(desc);
|
|
__be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
|
|
unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
|
|
|
|
sctx->buffer[partial++] = 0x80;
|
|
if (partial > bit_offset) {
|
|
memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial);
|
|
partial = 0;
|
|
|
|
block_fn(sctx, sctx->buffer, 1);
|
|
}
|
|
|
|
memset(sctx->buffer + partial, 0x0, bit_offset - partial);
|
|
*bits = cpu_to_be64(sctx->count << 3);
|
|
block_fn(sctx, sctx->buffer, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int sha1_base_finish(struct shash_desc *desc, u8 *out)
|
|
{
|
|
struct sha1_state *sctx = shash_desc_ctx(desc);
|
|
__be32 *digest = (__be32 *)out;
|
|
int i;
|
|
|
|
for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
|
|
put_unaligned_be32(sctx->state[i], digest++);
|
|
|
|
*sctx = (struct sha1_state){};
|
|
return 0;
|
|
}
|