Added some documentation to the asm instructions.
@@ -337,19 +337,30 @@ int s2n_get_rdrand_data(struct s2n_blob *out)
for (int tries = 0; tries < 10; tries++) {
/* yeah I'm not buying the whole "we can't use the mnemonic name instead of the opt-code,
- * we're already using a C99 compiler for Zeus sake. */
+ * we're already using a C99 compiler for Zeus sake.
+ * the following is taken directly from the intel manual:
+ * https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
+ * section 4.2 */
#if defined(__i386__)
unsigned char success_high = 0, success_low = 0;
+ /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
+ * output.i386_fields.u_low). Check the carry bit, which will be set on success_low.
+ * Then clober the register and reset the carry bit. */
__asm__ __volatile__("rdrand %0;\n" "setc %1;\n": "=r"(output.i386_fields.u_low), "=qm"(success_low)
:"r"(0)
:"cc");
-
+ /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
+ * output.i386_fields.u_high). Check the carry bit, which will be set on success_high.
+ * Then clober the register and reset the carry bit. */
__asm__ __volatile__("rdrand %0;\n" "setc %1;\n": "=r"(output.i386_fields.u_high), "=qm"(success_high)
:"r"(0)
:"cc");
success = success_high & success_low;
#else
+ /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
+ * output.u64). Check the carry bit, which will be set on success. Then clober the register and reset
+ * the carry bit. */
__asm__ __volatile__("rdrand %0;\n" "setc %1;\n": "=r"(output.u64), "=qm"(success)
:"r"(0)
:"cc");
