diff --git a/kernel/lib_log.c b/kernel/lib_log.c index 60f6f153..dea6f587 100644 --- a/kernel/lib_log.c +++ b/kernel/lib_log.c @@ -343,8 +343,10 @@ bool log_finalize(struct log_status *logst, int len, void (*endio)(void *private crc = 0; if (logst->do_crc) { - unsigned char checksum[mars_digest_size]; + unsigned char checksum[MARS_DIGEST_SIZE]; + mars_digest(checksum, data + logst->payload_offset, len); + /* FIXME: extend to MARS_DIGEST_SIZE */ crc = *(int*)checksum; } @@ -651,8 +653,10 @@ int log_scan(void *buf, *seq_nr = lh->l_seq_nr; if (lh->l_crc) { - unsigned char checksum[mars_digest_size]; + unsigned char checksum[MARS_DIGEST_SIZE]; + mars_digest(checksum, buf + found_offset, lh->l_len); + /* FIXME: extend to MARS_DIGEST_SIZE */ if (unlikely(*(int*)checksum != lh->l_crc)) { MARS_ERR(SCAN_TXT "data checksumming mismatch, length = %d\n", SCAN_PAR, lh->l_len); return -EBADMSG; diff --git a/kernel/mars.h b/kernel/mars.h index f79950cb..066d6b5b 100644 --- a/kernel/mars.h +++ b/kernel/mars.h @@ -112,6 +112,8 @@ // MARS-specific definitions +#define MARS_DIGEST_SIZE 16 + #define MARS_PRIO_HIGH -1 #define MARS_PRIO_NORMAL 0 // this is automatically used by memset() #define MARS_PRIO_LOW 1 @@ -183,7 +185,7 @@ enum _MREF_FLAGS { __u32 ref_flags; \ /* maintained by the ref implementation, readable for callers */ \ loff_t ref_total_size; /* just for info, need not be implemented */ \ - unsigned char ref_checksum[16]; \ + unsigned char ref_checksum[MARS_DIGEST_SIZE]; \ int ref_id; /* not mandatory; may be used for identification */ \ /* maintained by the ref implementation, incrementable for \ * callers (but not decrementable! use ref_put()) */ \ @@ -481,10 +483,9 @@ static inline void unuse_fake_mm(void) {} ///////////////////////////////////////////////////////////////////////// -/* Crypto stuff +/* Crypto / digest stuff */ -extern int mars_digest_size; extern void mars_digest(unsigned char *digest, void *data, int len); extern void mref_checksum(struct mref_object *mref); diff --git a/kernel/mars_generic.c b/kernel/mars_generic.c index 6b394b5f..a2a590a4 100644 --- a/kernel/mars_generic.c +++ b/kernel/mars_generic.c @@ -105,7 +105,7 @@ const struct meta mars_mref_meta[] = { META_INI(ref_cs_mode, struct mref_object, FIELD_INT), META_INI(ref_timeout, struct mref_object, FIELD_INT), META_INI(ref_total_size, struct mref_object, FIELD_INT), - META_INI(ref_checksum, struct mref_object, FIELD_INT), + META_INI(ref_checksum, struct mref_object, FIELD_RAW), META_INI(ref_flags, struct mref_object, FIELD_UINT), META_INI(ref_rw, struct mref_object, FIELD_INT), META_INI(ref_id, struct mref_object, FIELD_INT), @@ -134,8 +134,7 @@ EXPORT_SYMBOL_GPL(mars_lamport_time_meta); */ #include -static struct crypto_shash *mars_tfm = NULL; -int mars_digest_size = 0; +static struct crypto_shash *md5_tfm = NULL; struct mars_sdesc { struct shash_desc shash; @@ -144,14 +143,14 @@ struct mars_sdesc { void mars_digest(unsigned char *digest, void *data, int len) { - int size = sizeof(struct mars_sdesc) + crypto_shash_descsize(mars_tfm); + int size = sizeof(struct mars_sdesc) + crypto_shash_descsize(md5_tfm); struct mars_sdesc *sdesc = brick_mem_alloc(size); int status; - sdesc->shash.tfm = mars_tfm; + sdesc->shash.tfm = md5_tfm; sdesc->shash.flags = 0; - memset(digest, 0, mars_digest_size); + memset(digest, 0, MARS_DIGEST_SIZE); status = crypto_shash_digest(&sdesc->shash, data, len, digest); if (unlikely(status < 0)) MARS_ERR("cannot calculate cksum on %p len=%d, status=%d\n", @@ -161,6 +160,35 @@ void mars_digest(unsigned char *digest, void *data, int len) brick_mem_free(sdesc); } +static +int init_mars_digest(void) +{ + int status; + + md5_tfm = crypto_alloc_shash("md5", 0, 0); + if (unlikely(!md5_tfm) || IS_ERR(md5_tfm)) { + MARS_ERR("cannot alloc crypto hash, status=%ld\n", + PTR_ERR(md5_tfm)); + md5_tfm = NULL; + return -ELIBACC; + } + status = crypto_shash_digestsize(md5_tfm); + if (unlikely(status != MARS_DIGEST_SIZE)) { + MARS_ERR("md5 bad digest size %d\n", status); + return -ELIBACC; + } + + return 0; +} + +static +void exit_mars_digest(void) +{ + if (md5_tfm) { + crypto_free_shash(md5_tfm); + } +} + #else /* MARS_HAS_NEW_CRYPTO */ /* Old implementation, to disappear. @@ -172,7 +200,6 @@ void mars_digest(unsigned char *digest, void *data, int len) static struct crypto_hash *mars_tfm[OBSOLETE_TFM_MAX]; static struct semaphore tfm_sem[OBSOLETE_TFM_MAX]; -int mars_digest_size = 0; void mars_digest(unsigned char *digest, void *data, int len) { @@ -184,7 +211,7 @@ void mars_digest(unsigned char *digest, void *data, int len) }; struct scatterlist sg; - memset(digest, 0, mars_digest_size); + memset(digest, 0, MARS_DIGEST_SIZE); // TODO: use per-thread instance, omit locking down(&tfm_sem[i]); @@ -201,7 +228,7 @@ void mars_digest(unsigned char *digest, void *data, int len) void mref_checksum(struct mref_object *mref) { - unsigned char checksum[mars_digest_size]; + unsigned char checksum[MARS_DIGEST_SIZE]; int len; if (!(mref->ref_flags & MREF_CHKSUM_ANY) || !mref->ref_data) @@ -210,8 +237,8 @@ void mref_checksum(struct mref_object *mref) mars_digest(checksum, mref->ref_data, mref->ref_len); len = sizeof(mref->ref_checksum); - if (len > mars_digest_size) - len = mars_digest_size; + if (len > MARS_DIGEST_SIZE) + len = MARS_DIGEST_SIZE; memcpy(&mref->ref_checksum, checksum, len); } @@ -367,6 +394,8 @@ EXPORT_SYMBOL_GPL(mm_fake_count); int __init init_mars(void) { + int status; + MARS_INF("init_mars()\n"); set_fake(); @@ -388,14 +417,12 @@ int __init init_mars(void) #endif #ifdef MARS_HAS_NEW_CRYPTO - mars_tfm = crypto_alloc_shash("md5", 0, 0); - if (unlikely(!mars_tfm) || IS_ERR(mars_tfm)) { - MARS_ERR("cannot alloc crypto hash, status=%ld\n", - PTR_ERR(mars_tfm)); - return -ELIBACC; - } - mars_digest_size = crypto_shash_digestsize(mars_tfm); + status = init_mars_digest(); + if (unlikely(status)) + return status; + #else /* MARS_HAS_NEW_CRYPTO */ + { int i; @@ -418,9 +445,13 @@ int __init init_mars(void) return -EINVAL; } #endif - mars_digest_size = crypto_hash_digestsize(mars_tfm[0]); + status = crypto_hash_digestsize(mars_tfm[0]); + MARS_INF("digest_size = %d\n", status); + if (unlikely(status != MARS_DIGEST_SIZE)) { + MARS_ERR("bad md5 crypto hash size %d\n", status); + return -EINVAL; + } #endif /* MARS_HAS_NEW_CRYPTO */ - MARS_INF("digest_size = %d\n", mars_digest_size); return 0; } @@ -432,9 +463,7 @@ void exit_mars(void) put_fake(); #ifdef MARS_HAS_NEW_CRYPTO - if (mars_tfm) { - crypto_free_shash(mars_tfm); - } + exit_mars_digest(); #else /* MARS_HAS_NEW_CRYPTO */ if (mars_tfm[0]) { int i; diff --git a/kernel/sy_old/mars_main.c b/kernel/sy_old/mars_main.c index ef4450d1..1d24fdd9 100644 --- a/kernel/sy_old/mars_main.c +++ b/kernel/sy_old/mars_main.c @@ -1315,7 +1315,7 @@ int _update_version_link(struct mars_rotate *rot, struct trans_logger_info *inf) mars_digest(digest, data, len); len = 0; - for (i = 0; i < mars_digest_size; i++) { + for (i = 0; i < MARS_DIGEST_SIZE; i++) { len += sprintf(old + len, "%02x", digest[i]); }