Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/hastd/hast_checksum.c
Show All 25 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <strings.h> | #include <strings.h> | ||||
#ifdef HAVE_CRYPTO | |||||
#include <openssl/sha.h> | |||||
#endif | |||||
#include <crc32.h> | #include <crc32.h> | ||||
#include <hast.h> | #include <hast.h> | ||||
#include <nv.h> | #include <nv.h> | ||||
#include <sha256.h> | |||||
#include <pjdlog.h> | #include <pjdlog.h> | ||||
#include "hast_checksum.h" | #include "hast_checksum.h" | ||||
#ifdef HAVE_CRYPTO | |||||
#define MAX_HASH_SIZE SHA256_DIGEST_LENGTH | #define MAX_HASH_SIZE SHA256_DIGEST_LENGTH | ||||
#else | |||||
#define MAX_HASH_SIZE 4 | |||||
#endif | |||||
static void | static void | ||||
hast_crc32_checksum(const unsigned char *data, size_t size, | hast_crc32_checksum(const unsigned char *data, size_t size, | ||||
unsigned char *hash, size_t *hsizep) | unsigned char *hash, size_t *hsizep) | ||||
{ | { | ||||
uint32_t crc; | uint32_t crc; | ||||
crc = crc32(data, size); | crc = crc32(data, size); | ||||
/* XXXPJD: Do we have to use htole32() on crc first? */ | /* XXXPJD: Do we have to use htole32() on crc first? */ | ||||
bcopy(&crc, hash, sizeof(crc)); | bcopy(&crc, hash, sizeof(crc)); | ||||
*hsizep = sizeof(crc); | *hsizep = sizeof(crc); | ||||
} | } | ||||
#ifdef HAVE_CRYPTO | |||||
static void | static void | ||||
hast_sha256_checksum(const unsigned char *data, size_t size, | hast_sha256_checksum(const unsigned char *data, size_t size, | ||||
unsigned char *hash, size_t *hsizep) | unsigned char *hash, size_t *hsizep) | ||||
{ | { | ||||
SHA256_CTX ctx; | SHA256_CTX ctx; | ||||
SHA256_Init(&ctx); | SHA256_Init(&ctx); | ||||
SHA256_Update(&ctx, data, size); | SHA256_Update(&ctx, data, size); | ||||
SHA256_Final(hash, &ctx); | SHA256_Final(hash, &ctx); | ||||
*hsizep = SHA256_DIGEST_LENGTH; | *hsizep = SHA256_DIGEST_LENGTH; | ||||
} | } | ||||
#endif /* HAVE_CRYPTO */ | |||||
const char * | const char * | ||||
checksum_name(int num) | checksum_name(int num) | ||||
{ | { | ||||
switch (num) { | switch (num) { | ||||
case HAST_CHECKSUM_NONE: | case HAST_CHECKSUM_NONE: | ||||
return ("none"); | return ("none"); | ||||
Show All 13 Lines | checksum_send(const struct hast_resource *res, struct nv *nv, void **datap, | ||||
size_t hsize; | size_t hsize; | ||||
switch (res->hr_checksum) { | switch (res->hr_checksum) { | ||||
case HAST_CHECKSUM_NONE: | case HAST_CHECKSUM_NONE: | ||||
return (0); | return (0); | ||||
case HAST_CHECKSUM_CRC32: | case HAST_CHECKSUM_CRC32: | ||||
hast_crc32_checksum(*datap, *sizep, hash, &hsize); | hast_crc32_checksum(*datap, *sizep, hash, &hsize); | ||||
break; | break; | ||||
#ifdef HAVE_CRYPTO | |||||
case HAST_CHECKSUM_SHA256: | case HAST_CHECKSUM_SHA256: | ||||
hast_sha256_checksum(*datap, *sizep, hash, &hsize); | hast_sha256_checksum(*datap, *sizep, hash, &hsize); | ||||
break; | break; | ||||
#endif | |||||
default: | default: | ||||
PJDLOG_ABORT("Invalid checksum: %d.", res->hr_checksum); | PJDLOG_ABORT("Invalid checksum: %d.", res->hr_checksum); | ||||
} | } | ||||
nv_add_string(nv, checksum_name(res->hr_checksum), "checksum"); | nv_add_string(nv, checksum_name(res->hr_checksum), "checksum"); | ||||
nv_add_uint8_array(nv, hash, hsize, "hash"); | nv_add_uint8_array(nv, hash, hsize, "hash"); | ||||
if (nv_error(nv) != 0) { | if (nv_error(nv) != 0) { | ||||
errno = nv_error(nv); | errno = nv_error(nv); | ||||
return (-1); | return (-1); | ||||
Show All 15 Lines | if (algo == NULL) | ||||
return (0); /* No checksum. */ | return (0); /* No checksum. */ | ||||
rhash = nv_get_uint8_array(nv, &rhsize, "hash"); | rhash = nv_get_uint8_array(nv, &rhsize, "hash"); | ||||
if (rhash == NULL) { | if (rhash == NULL) { | ||||
pjdlog_error("Hash is missing."); | pjdlog_error("Hash is missing."); | ||||
return (-1); /* Hash not found. */ | return (-1); /* Hash not found. */ | ||||
} | } | ||||
if (strcmp(algo, "crc32") == 0) | if (strcmp(algo, "crc32") == 0) | ||||
hast_crc32_checksum(*datap, *sizep, chash, &chsize); | hast_crc32_checksum(*datap, *sizep, chash, &chsize); | ||||
#ifdef HAVE_CRYPTO | |||||
else if (strcmp(algo, "sha256") == 0) | else if (strcmp(algo, "sha256") == 0) | ||||
hast_sha256_checksum(*datap, *sizep, chash, &chsize); | hast_sha256_checksum(*datap, *sizep, chash, &chsize); | ||||
#endif | |||||
else { | else { | ||||
pjdlog_error("Unknown checksum algorithm '%s'.", algo); | pjdlog_error("Unknown checksum algorithm '%s'.", algo); | ||||
return (-1); /* Unknown checksum algorithm. */ | return (-1); /* Unknown checksum algorithm. */ | ||||
} | } | ||||
if (rhsize != chsize) { | if (rhsize != chsize) { | ||||
pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", | pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", | ||||
rhsize, algo, chsize); | rhsize, algo, chsize); | ||||
return (-1); /* Different hash size. */ | return (-1); /* Different hash size. */ | ||||
} | } | ||||
if (bcmp(rhash, chash, chsize) != 0) { | if (bcmp(rhash, chash, chsize) != 0) { | ||||
pjdlog_error("Hash mismatch."); | pjdlog_error("Hash mismatch."); | ||||
return (-1); /* Hash mismatch. */ | return (-1); /* Hash mismatch. */ | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } |