summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/checksum.c7
-rw-r--r--libglusterfs/src/checksum.h2
-rw-r--r--libglusterfs/src/libglusterfs.sym1
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c8
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c29
-rw-r--r--xlators/cluster/afr/src/afr.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c7
-rw-r--r--xlators/protocol/server/src/server-common.c3
-rw-r--r--xlators/storage/posix/src/posix-common.c16
-rw-r--r--xlators/storage/posix/src/posix-inode-fd-ops.c26
-rw-r--r--xlators/storage/posix/src/posix.h2
11 files changed, 89 insertions, 13 deletions
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index a7f9877ddf0..561ca04e48b 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -8,6 +8,7 @@
cases as published by the Free Software Foundation.
*/
+#include <openssl/md5.h>
#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
@@ -36,3 +37,9 @@ gf_rsync_strong_checksum (unsigned char *data, size_t len,
{
SHA256((const unsigned char *)data, len, sha256_md);
}
+
+void
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5)
+{
+ MD5 (data, len, md5);
+}
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
index bf7eeede8fc..677a59aa91e 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/checksum.h
@@ -17,4 +17,6 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len);
void
gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
+void
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5);
#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
index fa1e54d3663..b8dc496421c 100644
--- a/libglusterfs/src/libglusterfs.sym
+++ b/libglusterfs/src/libglusterfs.sym
@@ -643,6 +643,7 @@ gf_resolve_path_parent
gf_rev_dns_lookup
gf_rev_dns_lookup_cached
gf_rsync_strong_checksum
+gf_rsync_md5_checksum
gf_rsync_weak_checksum
gf_set_log_file_path
gf_set_log_ident
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 7e2a6027126..7195dfe058c 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -648,7 +648,13 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src)
if (dst->xdata)
dict_unref (dst->xdata);
dst->xdata = xdata;
- memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
+ if (xdata && dict_get_str_boolean (xdata, "fips-mode-rchecksum",
+ _gf_false) == _gf_true) {
+ memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
+ } else {
+ memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH);
+ }
+ dst->fips_mode_rchecksum = src->fips_mode_rchecksum;
}
void
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index bc710ea458f..3cf5b32b01d 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -38,11 +38,21 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
replies[i].valid = 1;
replies[i].op_ret = op_ret;
replies[i].op_errno = op_errno;
- if (xdata)
+ if (xdata) {
replies[i].buf_has_zeroes = dict_get_str_boolean (xdata,
"buf-has-zeroes", _gf_false);
- if (strong)
- memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH);
+ replies[i].fips_mode_rchecksum = dict_get_str_boolean (xdata,
+ "fips-mode-rchecksum", _gf_false);
+ }
+ if (strong) {
+ if (replies[i].fips_mode_rchecksum) {
+ memcpy (local->replies[i].checksum, strong,
+ SHA256_DIGEST_LENGTH);
+ } else {
+ memcpy (local->replies[i].checksum, strong,
+ MD5_DIGEST_LENGTH);
+ }
+ }
syncbarrier_wake (&local->barrier);
return 0;
@@ -58,11 +68,13 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
afr_local_t *local = NULL;
unsigned char *wind_subvols = NULL;
gf_boolean_t checksum_match = _gf_true;
+ struct afr_reply *replies = NULL;
dict_t *xdata = NULL;
int i = 0;
priv = this->private;
local = frame->local;
+ replies = local->replies;
xdata = dict_new();
if (!xdata)
@@ -83,16 +95,17 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (xdata)
dict_unref (xdata);
- if (!local->replies[source].valid || local->replies[source].op_ret != 0)
+ if (!replies[source].valid || replies[source].op_ret != 0)
return _gf_false;
for (i = 0; i < priv->child_count; i++) {
if (i == source)
continue;
- if (local->replies[i].valid) {
- if (memcmp (local->replies[source].checksum,
- local->replies[i].checksum,
- SHA256_DIGEST_LENGTH)) {
+ if (replies[i].valid) {
+ if (memcmp (replies[source].checksum,
+ replies[i].checksum,
+ replies[source].fips_mode_rchecksum ?
+ SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) {
checksum_match = _gf_false;
break;
}
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 220cc0b5d41..9f4e34a2afa 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -322,6 +322,7 @@ struct afr_reply {
/* For rchecksum */
uint8_t checksum[SHA256_DIGEST_LENGTH];
gf_boolean_t buf_has_zeroes;
+ gf_boolean_t fips_mode_rchecksum;
/* For lookup */
int8_t need_heal;
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index e293acfa2cc..5cfb1d0a9d3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2898,6 +2898,13 @@ struct volopt_map_entry glusterd_volopt_map[] = {
},
{ .option = "health-check-timeout",
.key = "storage.health-check-timeout",
+ .type = NO_DOC,
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
+ { .option = "fips-mode-rchecksum",
+ .key = "storage.fips-mode-rchecksum",
+ .type = NO_DOC,
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_4_0_0,
},
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
index 17660ef475e..071a1cf2714 100644
--- a/xlators/protocol/server/src/server-common.c
+++ b/xlators/protocol/server/src/server-common.c
@@ -299,7 +299,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->weak_checksum = weak_checksum;
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
- rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
+ rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
}
@@ -670,6 +670,7 @@ server4_post_rchecksum (gfx_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
+ rsp->flags = 1; /* Indicates SHA256 TYPE */
}
diff --git a/xlators/storage/posix/src/posix-common.c b/xlators/storage/posix/src/posix-common.c
index a67b3d7dc70..f1fa81e056b 100644
--- a/xlators/storage/posix/src/posix-common.c
+++ b/xlators/storage/posix/src/posix-common.c
@@ -387,6 +387,9 @@ posix_reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("max-hardlinks", priv->max_hardlinks,
options, uint32, out);
+
+ GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum,
+ options, bool, out);
ret = 0;
out:
return ret;
@@ -1076,6 +1079,9 @@ posix_init (xlator_t *this)
_private->create_directory_mask = create_directory_mask;
GF_OPTION_INIT ("max-hardlinks", _private->max_hardlinks, uint32, out);
+
+ GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum,
+ bool, out);
out:
if (ret) {
if (_private) {
@@ -1362,5 +1368,15 @@ struct volume_options options[] = {
.description = "max number of hardlinks allowed on any one inode.\n"
"0 is unlimited, 1 prevents any hardlinking at all."
},
+ {
+ .key = {"fips-mode-rchecksum"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .op_version = {GD_OP_VERSION_4_0_0},
+ .flags = OPT_FLAG_SETTABLE,
+ .tags = {"posix"},
+ .description = "If enabled, posix_rchecksum uses the FIPS compliant"
+ "SHA256 checksum. MD5 otherwise."
+ },
{ .key = {NULL} }
};
diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c
index 812cf792874..f3a2a7bfb83 100644
--- a/xlators/storage/posix/src/posix-inode-fd-ops.c
+++ b/xlators/storage/posix/src/posix-inode-fd-ops.c
@@ -4873,7 +4873,9 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
ssize_t bytes_read = 0;
int32_t weak_checksum = 0;
int32_t zerofillcheck = 0;
+ unsigned char md5_checksum[MD5_DIGEST_LENGTH] = {0};
unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0};
+ unsigned char *checksum = NULL;
struct posix_private *priv = NULL;
dict_t *rsp_xdata = NULL;
gf_boolean_t buf_has_zeroes = _gf_false;
@@ -4942,13 +4944,31 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
}
}
weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret);
- gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read,
- (unsigned char *) strong_checksum);
+ if (priv->fips_mode_rchecksum) {
+ ret = dict_set_int32 (rsp_xdata, "fips-mode-rchecksum", 1);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, -ret,
+ P_MSG_DICT_SET_FAILED, "%s: Failed to set "
+ "dictionary value for key: %s",
+ uuid_utoa (fd->inode->gfid),
+ "fips-mode-rchecksum");
+ goto out;
+ }
+ checksum = strong_checksum;
+ gf_rsync_strong_checksum ((unsigned char *)buf,
+ (size_t) bytes_read,
+ (unsigned char *)checksum);
+ } else {
+ checksum = md5_checksum;
+ gf_rsync_md5_checksum ((unsigned char *)buf,
+ (size_t) bytes_read,
+ (unsigned char *)checksum);
+ }
op_ret = 0;
out:
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno,
- weak_checksum, strong_checksum, rsp_xdata);
+ weak_checksum, checksum, rsp_xdata);
if (rsp_xdata)
dict_unref (rsp_xdata);
GF_FREE (alloc_buf);
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 5a623aa657a..08bcb1bddae 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -243,6 +243,8 @@ struct posix_private {
mode_t create_mask;
mode_t create_directory_mask;
uint32_t max_hardlinks;
+
+ gf_boolean_t fips_mode_rchecksum;
};
typedef struct {