<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb">
		<id>https://wiki.distorted.org.uk/act/history/Constant-time_subrange_copy?feed=atom</id>
		<title>Constant-time subrange copy - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.distorted.org.uk/act/history/Constant-time_subrange_copy?feed=atom"/>
		<link rel="alternate" type="text/html" href="https://wiki.distorted.org.uk/act/history/Constant-time_subrange_copy"/>
		<updated>2026-05-05T08:38:08Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>https://wiki.distorted.org.uk/w/index.php?title=Constant-time_subrange_copy&amp;diff=5&amp;oldid=prev</id>
		<title>Mdw: Created page with &quot;'''Objective:''' Given the address &lt;code&gt;p&lt;/code&gt; and length &lt;code&gt;psz&lt;/code&gt; of a source buffer, the address &lt;code&gt;q&lt;/code&gt; and length &lt;code&gt;qsz&lt;/code&gt; of a destination buffe...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.distorted.org.uk/w/index.php?title=Constant-time_subrange_copy&amp;diff=5&amp;oldid=prev"/>
				<updated>2016-10-18T00:52:39Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;Objective:&amp;#039;&amp;#039;&amp;#039; Given the address &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; and length &amp;lt;code&amp;gt;psz&amp;lt;/code&amp;gt; of a source buffer, the address &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; and length &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; of a destination buffe...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''Objective:''' Given the address &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; and length &amp;lt;code&amp;gt;psz&amp;lt;/code&amp;gt; of a source buffer, the address &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; and length &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; of a destination buffer, and a ''secret'' offset &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt;, copy up to &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; bytes starting from &amp;lt;code&amp;gt;p + o&amp;lt;/code&amp;gt; to the destination, without leaking &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
There are two obvious applications for this algorithm.&lt;br /&gt;
&lt;br /&gt;
* RSA PKCS #1 v1.5 decryption.  After applying the RSA private-key operation, the buffer contains &amp;lt;code&amp;gt;00&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;02&amp;lt;/code&amp;gt; || ''PS'' || &amp;lt;code&amp;gt;00&amp;lt;/code&amp;gt; || ''M'', where ''PS'' is a string of eight or more random nonzero padding bytes.  This scheme is, unfortunately, unaccountably popular despite it being broken in 1999.  There's a standard countermeasure if the payload ''M'' is supposed to be a random key, which involves substituting a fresh random key if the padding is bad; but doing this means that the ''entire process'' needs to run in constant time.&lt;br /&gt;
&lt;br /&gt;
* TLS MAC tag extraction.  A TLS record, prior to or after encryption, consists of a payload, a MAC tag, and between 1 and 256 bytes of padding.  Unfortunately, having the MAC ''inside'' the encryption and padding was a terrible mistake, leaving the whole scheme open to chosen-ciphertext attacks.  Checking the tag first means finding and extracting it, but that has to be done without leaking how much padding there is.&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
This algorithm is an improvement on the one used in Langley's code in OpenSSL.  It proceeds in two stages.&lt;br /&gt;
&lt;br /&gt;
* Firstly, copy the wanted bytes from the source to the destination. This requires a full pass over the source, but that's unavoidable if we want to equivocate on the secret offset.  The trick here (from OpenSSL) is that we get the right bytes, but not necessarily in the right places: they might end up rotated, by &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt; mod &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; bytes.&lt;br /&gt;
&lt;br /&gt;
* Secondly, undo the rotation so that the destination contains the correct data.  OpenSSL does the obvious &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt;&amp;amp;sup2; loop; but there's a better way: if we equivocate on each bit of the offset separately, we can undo the rotation in &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; log &amp;lt;code&amp;gt;qsz&amp;lt;/code&amp;gt; copies.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
WIP...&lt;/div&gt;</summary>
		<author><name>Mdw</name></author>	</entry>

	</feed>