]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Fix timing attacks in HMAC functions.
authorChris Porter <redacted>
Tue, 11 Jun 2013 22:02:42 +0000 (23:02 +0100)
committerChris Porter <redacted>
Tue, 11 Jun 2013 22:02:42 +0000 (23:02 +0100)
chanserv/authcmds/reset.c
chanserv/chanservcrypto.c
lib/hmac.c
lib/hmac.h
ticketauth/ticketauth.c
trusts/trusts_slave.c

index 54421652885b58d05fadc9bedf47c07274d3177e..cdea413e9a0464bb4aaa9719369a2d96e748eaab 100644 (file)
@@ -41,7 +41,7 @@ int csa_doreset(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
-  if(strcasecmp(cargv[1], csc_generateresetcode(rup->lockuntil, rup->username))) {
+  if(hmac_strcmp(cargv[1], csc_generateresetcode(rup->lockuntil, rup->username))) {
     chanservstdmessage(sender, QM_BADRESETCODE);
     return CMD_ERROR;
   }
index 05f70058ac3642fac949a8a25e9e398fb89a2ccb..ba40f437c7367dd89ae256f8ec60ee4e837a81f1 100644 (file)
@@ -119,7 +119,7 @@ int crsha1(char *username, const char *password, const char *challenge, const ch
 
   hmac_printhex(digest, hexbuf, sizeof(digest));
 
-  if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+  if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
     return 1;
 
   return 0;
@@ -148,7 +148,7 @@ int crsha256(char *username, const char *password, const char *challenge, const
   hmacsha256_update(&hmac, (unsigned char *)challenge, strlen(challenge));
   hmacsha256_final(&hmac, digest);
 
-  if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+  if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
     return 1;
 
   return 0;
@@ -177,7 +177,7 @@ int crmd5(char *username, const char *password, const char *challenge, const cha
   hmacmd5_update(&hmac, (unsigned char *)challenge, strlen(challenge));
   hmacmd5_final(&hmac, digest);
 
-  if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+  if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
     return 1;
 
   return 0;
@@ -194,7 +194,7 @@ int crlegacymd5(char *username, const char *password, const char *challenge, con
   MD5Update(&ctx, (unsigned char *)challenge, strlen(challenge));
   MD5Final(digest, &ctx);
 
-  if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+  if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
     return 1;
 
   return 0;
@@ -242,7 +242,7 @@ int cs_checkhashpass(const char *username, const char *password, const char *jun
   MD5Update(&ctx, (unsigned char *)buf, strlen(buf));
   MD5Final(digest, &ctx);
 
-  if(strcasecmp(hash, hmac_printhex(digest, hexbuf, sizeof(digest))))
+  if(hmac_strcmp(hash, hmac_printhex(digest, hexbuf, sizeof(digest))))
     return 0;
 
   return 1;
@@ -286,7 +286,7 @@ int csc_verifyqticket(char *data, char *digest) {
 
   hmac_printhex(digestbuf, hexbuf, sizeof(digestbuf));
 
-  if(!strcasecmp(hexbuf, digest))
+  if(!hmac_strcmp(hexbuf, digest))
     return 0;
 
   return 1;
index d4c255b73c0bcdbca681dc7b95dbd4dd1348568b..ee11d76e04569c45e6c1d3e3adf51c11b26af434 100644 (file)
@@ -130,3 +130,19 @@ char *hmac_printhex(unsigned char *data, char *out, size_t len) {
   *o = '\0';
   return out;
 }
+
+int hmac_strcmp(char *a, char *b) {
+  int result = 1;
+
+  if(!a || !b)
+    return 1;
+
+  if(strlen(a) != strlen(b))
+    return 1;
+
+  while(*a)
+    result&=(tolower(*a++) == tolower(*b++));
+
+  return !result;
+}
+
index 6c149d2b7095fd2dfc43d5e72c4efb673b3bfe28..3a5a09360765001096597b3174dec3a4928d7423 100644 (file)
@@ -27,3 +27,5 @@ void hmacmd5_update(hmacmd5 *c, unsigned char *message, int messagelen);
 void hmacmd5_init(hmacmd5 *c, unsigned char *key, int keylen);
 
 char *hmac_printhex(unsigned char *data, char *out, size_t len);
+
+int hmac_strcmp(char *a, char *b);
index da8b353358c7e943bf7cf0ea4f70ed9fa94f51da..40bd8b5d5f21ce5728d73f5f479592ef5d79ee9d 100644 (file)
@@ -68,7 +68,7 @@ int ta_ticketauth(void *source, int cargc, char **cargv) {
   /* hahahaha */
   snprintf(buffer, sizeof(buffer), "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", digest[0], digest[1],  digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22], digest[23], digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30], digest[31]);
 
-  if(strcasecmp(buffer, uhmac)) {
+  if(hmac_strcmp(buffer, uhmac)) {
     controlwall(NO_OPER, NL_MISC, "%s!%s@%s attempted to TICKETAUTH as %s (bad HMAC)", np->nick, np->ident, np->host->name->content, acc);
     controlreply(np, "Bad HMAC.");
     return CMD_ERROR;
index c62f14567a801d1d2b9a24d88db0e589106b7366..38029029d1c29479e3db1789e028c7ea84a9cf65 100644 (file)
@@ -235,7 +235,7 @@ static int xsb_trfini(void *source, int argc, char **argv) {
   }
 
   SHA1Final(digest, &s);
-  if(strcasecmp(hmac_printhex(digest, digestbuf, SHA1_DIGESTSIZE), buf)) {
+  if(hmac_strcmp(hmac_printhex(digest, digestbuf, SHA1_DIGESTSIZE), buf)) {
     abandonreplication("digest mismatch");
     return CMD_ERROR;
   }