static int verify_digest(char *tbuf, int t_size, fko_ctx_t ctx) { #if AFL_FUZZING return FKO_SUCCESS; #endif switch(ctx->digest_type) { case FKO_DIGEST_MD5: md5_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA1: sha1_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA256: sha256_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA384: sha384_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA512: sha512_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; /* Note that we check SHA3_256 and SHA3_512 below because the * digest lengths for these are the same as SHA256 and SHA512 * respectively, and setting the digest type for an incoming * decrypted SPA packet is done initially by looking at the * length. */ default: /* Invalid or unsupported digest */ return(FKO_ERROR_INVALID_DIGEST_TYPE); } /* We give up here if the computed digest does not match the * digest in the message data. */ if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { /* Could potentially also have been SHA3_256 or SHA3_512 */ if(ctx->digest_type == FKO_DIGEST_SHA256) { memset(tbuf, 0, FKO_ENCODE_TMP_BUF_SIZE); sha3_256_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } else { ctx->digest_type = FKO_DIGEST_SHA3_256; ctx->digest_len = SHA3_256_B64_LEN; } } else if(ctx->digest_type == FKO_DIGEST_SHA512) { memset(tbuf, 0, FKO_ENCODE_TMP_BUF_SIZE); sha3_512_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } else { ctx->digest_type = FKO_DIGEST_SHA3_512; ctx->digest_len = SHA3_512_B64_LEN; } } else return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } return FKO_SUCCESS; }
static int set_digest(char *data, char **digest, short digest_type, int *digest_len) { char *md = NULL; int data_len; data_len = strnlen(data, MAX_SPA_ENCODED_MSG_SIZE); #if HAVE_LIBFIU fiu_return_on("set_digest_toobig", FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG); #endif if(data_len == MAX_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG); #if HAVE_LIBFIU fiu_return_on("set_digest_invalidtype", FKO_ERROR_INVALID_DIGEST_TYPE); fiu_return_on("set_digest_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif switch(digest_type) { case FKO_DIGEST_MD5: md = calloc(1, MD_HEX_SIZE(MD5_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); md5_base64(md, (unsigned char*)data, data_len); *digest_len = MD5_B64_LEN; break; case FKO_DIGEST_SHA1: md = calloc(1, MD_HEX_SIZE(SHA1_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha1_base64(md, (unsigned char*)data, data_len); *digest_len = SHA1_B64_LEN; break; case FKO_DIGEST_SHA256: md = calloc(1, MD_HEX_SIZE(SHA256_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha256_base64(md, (unsigned char*)data, data_len); *digest_len = SHA256_B64_LEN; break; case FKO_DIGEST_SHA384: md = calloc(1, MD_HEX_SIZE(SHA384_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha384_base64(md, (unsigned char*)data, data_len); *digest_len = SHA384_B64_LEN; break; case FKO_DIGEST_SHA512: md = calloc(1, MD_HEX_SIZE(SHA512_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha512_base64(md, (unsigned char*)data, data_len); *digest_len = SHA512_B64_LEN; break; case FKO_DIGEST_SHA3_256: md = calloc(1, MD_HEX_SIZE(SHA3_256_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha3_256_base64(md, (unsigned char*)data, data_len); *digest_len = SHA3_256_B64_LEN; break; case FKO_DIGEST_SHA3_512: md = calloc(1, MD_HEX_SIZE(SHA3_512_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha3_512_base64(md, (unsigned char*)data, data_len); *digest_len = SHA3_512_B64_LEN; break; default: return(FKO_ERROR_INVALID_DIGEST_TYPE); } /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(*digest != NULL) free(*digest); *digest = md; return(FKO_SUCCESS); }