-static void
-Hi(const struct hash_method *hmethod, const unsigned char *str, size_t str_size,
- const unsigned char *salt, size_t salt_size, unsigned int i,
- unsigned char *result)
+/* Copyright (c) 2022-2023 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "hmac.h"
+
+#include "auth-scram.h"
+
+void auth_scram_hi(const struct hash_method *hmethod,
+ const unsigned char *str, size_t str_size,
+ const unsigned char *salt, size_t salt_size, unsigned int i,
+ unsigned char *result)
{
struct hmac_context ctx;
unsigned char U[hmethod->digest_size];
unsigned int j, k;
+ /* Hi(str, salt, i):
+
+ U1 := HMAC(str, salt + INT(1))
+ U2 := HMAC(str, U1)
+ ...
+ Ui-1 := HMAC(str, Ui-2)
+ Ui := HMAC(str, Ui-1)
+
+ Hi := U1 XOR U2 XOR ... XOR Ui
+
+ where "i" is the iteration count, "+" is the string concatenation
+ operator, and INT(g) is a 4-octet encoding of the integer g, most
+ significant octet first.
+ */
+
/* Calculate U1 */
hmac_init(&ctx, str, str_size, hmethod);
hmac_update(&ctx, salt, salt_size);
--- /dev/null
+#ifndef AUTH_SCRAM_H
+#define AUTH_SCRAM_H
+
+void auth_scram_hi(const struct hash_method *hmethod,
+ const unsigned char *str, size_t str_size,
+ const unsigned char *salt, size_t salt_size, unsigned int i,
+ unsigned char *result);
+
+#endif
#include "sha1.h"
#include "sha2.h"
#include "str.h"
+#include "auth-scram.h"
#include "password-scheme.h"
/* SCRAM allowed iteration count range. RFC says it SHOULD be at least 4096 */
#define SCRAM_DEFAULT_ITERATE_COUNT 4096
-#include "auth-scram.c"
-
int scram_scheme_parse(const struct hash_method *hmethod, const char *name,
const unsigned char *credentials, size_t size,
unsigned int *iter_count_r, const char **salt_r,
salt = buffer_get_data(t_base64_decode_str(salt_base64), &salt_len);
/* FIXME: credentials should be SASLprepped UTF8 data here */
- Hi(hmethod, (const unsigned char *)plaintext, strlen(plaintext),
- salt, salt_len, iter_count, salted_password);
+ auth_scram_hi(hmethod,
+ (const unsigned char *)plaintext, strlen(plaintext),
+ salt, salt_len, iter_count, salted_password);
/* Calculate ClientKey */
hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
base64_encode(salt, sizeof(salt), str);
/* FIXME: credentials should be SASLprepped UTF8 data here */
- Hi(hmethod, (const unsigned char *)plaintext, strlen(plaintext), salt,
- sizeof(salt), rounds, salted_password);
+ auth_scram_hi(hmethod,
+ (const unsigned char *)plaintext, strlen(plaintext),
+ salt, sizeof(salt), rounds, salted_password);
/* Calculate ClientKey */
hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);