Browse Source

add byte_start, byte_starts

add a man page for byte_equal_notimingattack
master
Felix von Leitner 1 year ago
parent
commit
966c3f4d2f
  1. 2
      CHANGES
  2. 16
      byte.h
  3. 8
      byte/byte_equal.3
  4. 17
      byte/byte_equal_notimingattack.3
  5. 20
      byte/byte_start.3
  6. 16
      byte/byte_start.c
  7. 24
      byte/byte_starts.3
  8. 24
      byte/byte_starts.c

2
CHANGES

@ -1,4 +1,6 @@
0.33:
add byte_start, byte_starts
add a man page for byte_equal_notimingattack
0.32:
remove OpenBSD #warning (obsd maintainer says no longer needed)

16
byte.h

@ -56,6 +56,22 @@ void byte_zero(void* out, size_t len);
#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
/* Return 1 iff (b,blen) is a prefix of (a,alen), 0 otherwise.
* Will abort early on mismatch */
__readmemsz__(1,2)
__readmemsz__(3,4)
int byte_start(const void* a,size_t alen,const void* b,size_t blen) __pure__;
/* equivalent to byte_start(a,alen,str,strlen(str)) */
__readmemsz__(1,2)
__readmem__(3)
int byte_starts(const void* a,size_t alen,const char* str) __pure__;
#if defined(__GNUC__) && !defined(__LIBOWFAT_INTERNAL)
/* If str is a string constant, strlen will be done at compile time */
#define byte_starts(a,alen,str) (__builtin_constant_p(str) ? byte_start(a,alen,str,strlen(str)) : byte_starts(a,alen,str))
#endif
__readmemsz__(1,2)
__readmemsz__(3,2)
int byte_equal_notimingattack(const void* a, size_t len,const void* b) __pure__;

8
byte/byte_equal.3

@ -9,7 +9,11 @@ int \fBbyte_equal\fP(const char *\fIone\fR,size_t \fIlen\fR,const char *\fItwo\f
\fIbyte_equal\fR returns 1 if the strings are equal, 0 otherwise.
When the strings are different, byte_equal does not read bytes past the
first difference.
first difference. An attacker observing the execution timing can thus
learn where the first mismatch happened.
Use byte_equal_notimingattack to compare keys, passphrases, cookies or
hashes instead.
.SH "SEE ALSO"
byte_diff(3)
byte_diff(3), byte_equal_notimingattack(3)

17
byte/byte_equal_notimingattack.3

@ -0,0 +1,17 @@
.TH byte_equal_notimingattack 3
.SH NAME
byte_equal_notimingattack \- compare two strings
.SH SYNTAX
.B #include <libowfat/byte.h>
int \fBbyte_equal_notimingattack\fP(const char *\fIone\fR,size_t \fIlen\fR,const char *\fItwo\fR);
.SH DESCRIPTION
\fIbyte_equal_notimingattack\fR returns 1 if the strings are equal, 0 otherwise.
When the strings are different, byte_equal_notimingattack will still
read and compare all the other bytes. That way, an attacker observing
the timing of the execution can not learn where the first mismatch
occurred.
.SH "SEE ALSO"
byte_diff(3), byte_equal(3)

20
byte/byte_start.3

@ -0,0 +1,20 @@
.TH byte_start 3
.SH NAME
byte_start \- find out if string b is prefix of string a
.SH SYNTAX
.B #include <libowfat/byte.h>
int \fBbyte_start\fP(const char *\fIa\fR,size_t \fIalen\fR,const char *\fIb\fR,size_t blen);
.SH DESCRIPTION
\fIbyte_start\fR returns 1 if \fIalen\fR >= \fIblen\fR and the first \fIblen\fR bytes from
\fIa\fR and \fIb\fR are equal.
When \fIblen\fR is too large or the strings are different, \fIbyte_start\fR does not
read bytes past the first difference. An attacker observing the
execution timing can thus learn where the first mismatch happened.
Use \fIbyte_equal_notimingattack\fR to compare keys, passphrases, cookies or
hashes instead.
.SH "SEE ALSO"
byte_equal(3), byte_equal_notimingattack(3), byte_starts(3)

16
byte/byte_start.c

@ -0,0 +1,16 @@
#include <byte.h>
#include <string.h>
int byte_start(const void* a,size_t alen,const void* b,size_t blen) {
return blen<=alen && !memcmp(a,b,blen);
}
#ifdef UNITTEST
#include <assert.h>
int main() {
static char buf[]="The quick brown fox jumps over the lazy dog";
assert(byte_start(buf,sizeof(buf)-1,"The ",4));
assert(!byte_start(buf,sizeof(buf)-1,"the ",4));
assert(!byte_start(buf,3,buf,9));
}
#endif

24
byte/byte_starts.3

@ -0,0 +1,24 @@
.TH byte_starts 3
.SH NAME
byte_starts \- find out if a buffer starts with a string
.SH SYNTAX
.B #include <libowfat/byte.h>
int \fBbyte_starts\fP(const char *\fIbuf\fR,size_t \fIbuflen\fR,const char *\fIstr\fR);
.SH DESCRIPTION
\fIbyte_starts\fR returns 1 if the \fIbuflen\fR>=strlen(\fIstr\fR) and the first
strlen(\fIstr\fR) bytes of \fIbuf\fR match the contents of \fIstr\fR, or
0 otherwise.
This function is meant to be used in protocol parsing and with a string
constant for \fIstr\fR and will use gcc/clang macro trickery to reduce to a call to
\fImemcmp\fR then.
\fIbyte_starts\fR compares as few bytes as possible. An attacker observing
the execution timing can thus learn where the first mismatch happened.
Use \fIbyte_equal_notimingattack\fR to compare keys, passphrases, cookies or
hashes instead.
.SH "SEE ALSO"
byte_equal(3), byte_equal_notimingattack(3), byte_start(3)

24
byte/byte_starts.c

@ -0,0 +1,24 @@
#include <byte.h>
#undef byte_starts
#include <string.h>
int byte_starts(const void* a,size_t alen,const char* s) {
size_t i;
for (i=0; i<alen; ++i) {
if (s[i]==0) return 1;
if (((const char*)a)[i] != s[i]) return 0;
}
return s[i]==0;
}
#ifdef UNITTEST
#include <assert.h>
int main() {
static char buf[]="The quick brown fox jumps over the lazy dog";
assert(byte_starts(buf,sizeof(buf)-1,"The "));
assert(!byte_starts(buf,sizeof(buf)-1,"the "));
assert(!byte_starts(buf,2,"The "));
assert(byte_starts("The ",4,"The "));
}
#endif
Loading…
Cancel
Save