<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-6269139839497360743</id><updated>2009-10-12T21:41:33.187-07:00</updated><title type='text'>Obfuscated TCP</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default?start-index=26&amp;max-results=25'/><author><name>Adam Langley</name><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-6352599666420159028</id><published>2008-10-20T18:56:00.000-07:00</published><updated>2008-10-20T18:58:11.102-07:00</updated><title type='text'>Windows Firefox installer</title><content type='html'>Thanks to &lt;span class="HcCDpe"&gt;&lt;span class="EP8xU" email="arthur.casals@gmail.com" style="color: #00681c;"&gt;&lt;span style="color: black;"&gt;Arthur Casals,&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;we have a Windows installer! See the &lt;a href="http://code.google.com/p/obstcp/wiki/Firefox"&gt;Firefox page&lt;/a&gt; for the link.&lt;br /&gt;&lt;br /&gt;This version only supports TLS transport however, in order to keep the build issues sane! The TLS only Firefox patch is quite small and I'll try to push it upstream at some point. However, Chrome is keeping me busy at the moment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-6352599666420159028?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/6352599666420159028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=6352599666420159028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6352599666420159028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6352599666420159028'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/10/windows-firefox-installer.html' title='Windows Firefox installer'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-3674827745692617892</id><published>2008-10-09T15:55:00.000-07:00</published><updated>2008-10-09T16:02:12.567-07:00</updated><title type='text'>We hit Slashdot</title><content type='html'>We hit Slashdot on Tuesday, the craze is dying down now.&lt;br /&gt;&lt;br /&gt;I think I learn two things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The introduction video was a bit crappy and several people, rightly, said so. However, the general level of misunderstanding was substantially reduced, so it worked I guess&lt;/li&gt;&lt;li&gt;I should be provided a transcript of the video or, at least, a non-video replacement for it. I've now done this.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;TLS transport support&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;TLS transport support is here, yay! Well, it's just hitting the site now. In short, you can configure the DNS advert to say "Actually, connect with HTTPS on port &lt;i&gt;x&lt;/i&gt;". Firefox will see this and, even when the user entered "http://", will use HTTPS and ignore any certificate problems.&lt;br /&gt;&lt;br /&gt;This makes server support easy, it's just HTTPS. Performance isn't so great, but, well, there you go. Port 443 also works better with firewalls.&lt;br /&gt;&lt;br /&gt;The documentation and git trees are up to date. I'll be uploading the Firefox build (64-bit Linux) in just a second.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-3674827745692617892?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/3674827745692617892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=3674827745692617892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3674827745692617892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3674827745692617892'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/10/we-hit-slashdot.html' title='We hit Slashdot'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-4835333373552342881</id><published>2008-10-06T18:12:00.000-07:00</published><updated>2008-10-06T18:14:03.589-07:00</updated><title type='text'>ABI break, wire break</title><content type='html'>I've switched the default cipher from Salsa20 to Salsa20/8. I had always intended to do this, it was just a question of getting a good implementation of Salsa20/8 first.&lt;br /&gt;&lt;br /&gt;However, this entails an ABI and wire protocol break. Hopefully there won't be many more of these. So I've uploaded new tarballs for Firefox and libobstcp. Also, there's now a tarball for Firefox built on IA32 Linux (currently untested).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-4835333373552342881?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/4835333373552342881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=4835333373552342881' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4835333373552342881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4835333373552342881'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/10/abi-break-wire-break.html' title='ABI break, wire break'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-4782902127205583763</id><published>2008-10-03T11:35:00.000-07:00</published><updated>2008-10-03T11:37:42.998-07:00</updated><title type='text'>Testing needed</title><content type='html'>Ok, all the documentation on the site has been updated. There is now new code (using DNS adverts), a new video introduction, new Firefox patches etc.&lt;br /&gt;&lt;br /&gt;Please, if you have any time, goto &lt;a href="http://code.google.com/p/obstcp"&gt;the code site&lt;/a&gt;, act dumb, watch the video and follow the instructions, either as just a user, or as a webmaster too.&lt;br /&gt;&lt;br /&gt;Tell me what doesn't work and what doesn't make sense.&lt;br /&gt; &lt;br /&gt;Cheers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-4782902127205583763?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/4782902127205583763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=4782902127205583763' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4782902127205583763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4782902127205583763'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/10/testing-needed.html' title='Testing needed'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-2387308923819728170</id><published>2008-09-30T19:46:00.000-07:00</published><updated>2008-09-30T19:51:22.781-07:00</updated><title type='text'>DNS support</title><content type='html'>It's been a couple of weeks since I worked on ObsTCP. There has been some public key signature work and family matters in between.&lt;br /&gt;&lt;br /&gt;However, I did have a stonking good idea today (with partial credit to djb).&lt;br /&gt;&lt;br /&gt;Previously I intended to encode adverts in a DNS TXT record under a special name. This would mean writing a custom resolver to handle this and doubling the number of DNS lookups for each host.&lt;br /&gt;&lt;br /&gt;However, if I encode the advert in a CNAME, I don't need either.&lt;br /&gt;&lt;br /&gt;Consider &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;www.example.com&lt;/span&gt;, a CNAME for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;opa12354zbcdefghijkl12345.example.com&lt;/span&gt;. When one performs a lookup for an A record for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;www.example.com&lt;/span&gt;, the server will return the A record &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;opa&lt;/span&gt;...&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;example.co&lt;/span&gt;m and the CNAME record for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;www&lt;/span&gt;. By encoding the advert in the CNAME, we don't need an additional request.&lt;br /&gt;&lt;br /&gt;Also, the CNAME chain is returned by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;gethostbyname&lt;/span&gt; (but not &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getaddrinfo&lt;/span&gt;), thus we can use the standard libc resolver too.&lt;br /&gt;&lt;br /&gt;I'm very happy with this. I'm patching up Firefox now to use gethostbyname and to parse adverts from DNS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-2387308923819728170?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/2387308923819728170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=2387308923819728170' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2387308923819728170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2387308923819728170'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/09/dns-support.html' title='DNS support'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-4601525469124766226</id><published>2008-09-11T14:58:00.000-07:00</published><updated>2008-09-11T15:01:02.795-07:00</updated><title type='text'>New release: 0.2</title><content type='html'>Another week, another release. This week brings lots of rewriting of the core to be cleaner and Apache support.&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://code.google.com/p/obstcp"&gt;project page&lt;/a&gt; for details. Remember that, if you're installing 0.2 you should download a new Firefox, repatch lighttpd etc. Also, when you &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;make install&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;, &lt;/span&gt;if you have processes linked against a shared library that you override, they'll probably crash.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-4601525469124766226?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/4601525469124766226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=4601525469124766226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4601525469124766226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4601525469124766226'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/09/new-release-02.html' title='New release: 0.2'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-5934726152350137158</id><published>2008-09-03T18:37:00.000-07:00</published><updated>2008-10-07T19:12:56.145-07:00</updated><title type='text'>Obfuscated TCP (take 3) ready for alpha testing</title><content type='html'>Well, after rewriting it again, the new design is ready for testing!&lt;br /&gt;&lt;br /&gt;Not all of the old pages have been updated, but most have. Start at &lt;a href="http://code.google.com/p/obstcp/wiki/Testing"&gt;http://code.google.com/p/obstcp/wiki/Testing&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This time it doesn't involve any kernel patching. You just install the core library, download a patched Firefox binary, install a Firefox extension and you're done!&lt;br /&gt;&lt;br /&gt;I'll be working on some more documentation tonight / tomorrow.&lt;br /&gt;&lt;br /&gt;If you try it (sucessfully or otherwise) please tell me. Comments on the blog, comments on the site (&lt;a href="http://code.google.com/p/obstcp"&gt;http://code.google.com/p/obstcp&lt;/a&gt;), mailing list posts (&lt;a href="http://groups.google.com/group/obstcp"&gt;http://groups.google.com/group/obstcp&lt;/a&gt;) or email (agl AT imperialviolet DOT org) all welcome.&lt;br /&gt;&lt;br /&gt;And, of course, you should thank Google, who are still employing me as I write this. &lt;span style="font-style: italic;"&gt;Although no support of the idea by Google, as a company, is implied.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-5934726152350137158?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/5934726152350137158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=5934726152350137158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5934726152350137158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5934726152350137158'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/09/obfuscated-tcp-take-3-ready-for-alpha.html' title='Obfuscated TCP (take 3) ready for alpha testing'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-4306751283323694131</id><published>2008-08-28T19:41:00.000-07:00</published><updated>2008-08-28T19:42:31.733-07:00</updated><title type='text'></title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_kRcqvZJgJFs/SLdh4KdyriI/AAAAAAAAAUw/qoQBeJf9k-s/s1600-h/minefield.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_kRcqvZJgJFs/SLdh4KdyriI/AAAAAAAAAUw/E5_sRA3YYRk/s400-R/minefield.png" /&gt;&lt;/a&gt;&lt;/div&gt;The firefox modifications to support Obfuscated TCP appear to be working. There's still a fair bit of work until they exist as an extension rather than a source patch however.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-4306751283323694131?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/4306751283323694131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=4306751283323694131' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4306751283323694131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/4306751283323694131'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/firefox-modifications-to-support.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_kRcqvZJgJFs/SLdh4KdyriI/AAAAAAAAAUw/E5_sRA3YYRk/s72-Rc/minefield.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-6100916880848095260</id><published>2008-08-26T16:30:00.000-07:00</published><updated>2008-08-26T16:43:48.149-07:00</updated><title type='text'></title><content type='html'>I've written the new &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;libobstcp&lt;/span&gt;, it's not in a final state yet (of course), but it's functional. The header file is included below, I'll release the source once there's a client side implementation (maybe as a Firefox extension).&lt;br /&gt;&lt;br /&gt;The design is thus:I started writing the HTTP-in-HTTP encapsulation and discovered that it's really hideous. I don't think anything that feels so wrong can be a good design decision, so, here's the main point: it's using a different port number for obfuscation now.&lt;br /&gt;&lt;br /&gt;The client finds out the alternative port number via an "advert" for the server. The advert can either be in the DNS, or can be remembered from previous (non-obfuscated) HTTP connections where the advert is returned by the server in an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;X-ObsTCP&lt;/span&gt; header. The advert is a small, base64 encoded string that contains the server's public key, obfuscated port number, and (optionally) the TLS port number.&lt;br /&gt;&lt;br /&gt;This isn't specific to HTTP, the general idea is that the advert is a way of saying "This service is alternatively available over ObsTCP/TLS on these ports...". The advert is a tagged format, so there's room to extend it in the future. Planned extensions currently include integrety protection for the data stream using either packet signing in the kernel or MACs at the application layer (or both).&lt;br /&gt;&lt;br /&gt;So, the major work at the moment is writing a Firefox extension to do this. Firefox is a big piece of code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #cd00cd;"&gt;#ifndef LIBOBSTCP_H&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #cd00cd;"&gt;#define LIBOBSTCP_H&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #cd00cd;"&gt;#include &lt;/span&gt;&lt;span style="color: #00cd00;"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #cd00cd;"&gt;#include &lt;/span&gt;&lt;span style="color: #00cd00;"&gt;&amp;lt;sys/uio.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// struct obstcp_keypair - a public/private key pair&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// keyid: the 32-bit xor folding of the public key&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keypair {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;private_key[&lt;span style="color: #00cd00;"&gt;32&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;public_key[&lt;span style="color: #00cd00;"&gt;32&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint32_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;keyid;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keypair *next;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keypair *keys;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Setup a keyset structure. This must be called before any other operations&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// on the keyset.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys_init(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys);&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Calculate the public key from a private key and prepend the key pair to the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// list of keys installed in the keyset. This becomes the default key&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: 1 on success, 0 on error, in which case errno is set:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; ENOMEM: out of memory&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; ENOSPC: a key with the same keyid is already in the keyset&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys_key_add(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys, &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*private_key);&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Free all keys contained in the keyset&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys_free(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Keys for the variable arguments part of obstcp_advert_create and&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// obstcp_advert_parse&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;enum&lt;/b&gt;&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;OBSTCP_ADVERT_END = &lt;span style="color: #00cd00;"&gt;0&lt;/span&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// no argument&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;OBSTCP_ADVERT_OBSPORT,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// takes an int giving the port&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;OBSTCP_ADVERT_TLSPORT,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// takes an int giving the port&lt;/span&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Generate a base64 encoded obstcp "advert", this is the data that can be&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// included in a DNS TXT record of via other side channels. It takes a variable&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// argument list. The variable part of the argument list are a series of pairs&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// where the first element of the pair is one of OBSTCP_ADVERT_* and the second&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// depends on the value of the first, and may not even exist. The default key&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// from the keyset is used for the public value.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// The variable list must be terminated with OBSTCP_ADVERT_END.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// output: a buffer to which the base64 encoded data is written&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// length: number of bytes of space in @output&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: on success a value &amp;lt;= to @length is returned. This is the number of&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; bytes written. If @output was too small, a value &amp;gt; @length is returned.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; This is the number of bytes that is required. Otherwise -1 is returned and&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; errno is set:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; E2BIG: too many options were selected&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; EINVAL: an unknown or invalid pair was found in the arguments&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; ENOKEY: no default key was found in the keyset&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_advert_create(&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*output, &lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;length,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys, ...);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Parse a base64 encoded obstcp "advert". This can be used to extract the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// advertised obfuscated and TLS port numbers.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// The variable arguments come in pairs. The first of each pair is one of&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// OBSTCP_ADVERT_* which are shared with obstcp_advert_create, above. However,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// since this is a parsing function, where, say, OBSTCP_ADVERT_OBSPORT is&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// documented as having an int as its second element, for this function is&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// would be a pointer to an int.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// The variable list must be terminated with OBSTCP_ADVERT_END.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// For elements which aren't found a special value is used to denote this. For&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// port numbers, this value is 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// input: the base64 encoded banner&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// length: the number of bytes in @input (not inc \n etc)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: 1 on success, 0 on parse error.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_advert_parse(&lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*input, &lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;length, ...);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// This is the crypto context for a given direction of data&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_half_connection {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;keystream[&lt;span style="color: #00cd00;"&gt;64&lt;/span&gt;];&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// keystream bytes&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;used;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// number of bytes of @keystream used&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint32_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;input[&lt;span style="color: #00cd00;"&gt;16&lt;/span&gt;];&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// salsa20 context&lt;/span&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Server interfaces...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// These functions are designed to be used by the 'server' side of the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// connection. It's up to the user of this library to decide which side is the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// server, it doesn't have to correspond to the sockets API notion of a server,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// although it's expected that it usually will.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;union&lt;/b&gt;&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;buffer[&lt;span style="color: #00cd00;"&gt;386&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;read;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} a;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_half_connection in;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_half_connection out;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;} u;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;state;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;frame_open, frame_valid;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Setup a context structure. This must be called before any other operations&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// on the context struture.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx_init(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Read from a socket&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// fd: the file descriptor to read from&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// buffer: buffer to write data to&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// len: number of bytes in @buffer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// ready: (output) on success, this is true if a MAC was successfully&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; calculated.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Reading from a socket has two phases:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; 1) setup phase, before key agreement has completed. In this phase this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function with return -1 with errno set to EAGAIN until it has enough&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data to complete key agreement.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If key agreement is successful, we move to phase two. Otherwise, we&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return -1 and set errno to EPROTO.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; 2) In this phase we are reading application data from the socket. It may&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;be that the data is MAC protected. In this case, the read calls will&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return positive byte counts, but *ready will be false on return. Once&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;the MAC has been read and checked *ready will be true. This means that&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all the data since the last time ready returned true is valid and can&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;be processed. There cannot be &amp;gt; 16K of unready data.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Do not use this for application level framing since MAC may not be in&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;operation - in this case *ready is always set to true.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Otherwise, this call returns like read(2) - i.e. 0 return means EOF etc. One&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// exception is that this call will never return -1 with an errno of EINTR. The&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// socket can be blocking or non-blocking.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// If you wish to know if key agreement has completed after calling this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// function, use obstcp_server_ready.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;ssize_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_read(&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;fd, &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*buffer, &lt;span style="color: blue;"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;len, &lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*ready);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Returns true iff key agreement has completed.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ready(&lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx *ctx);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Write examples:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Simple case: in this case, the application is writing blocks of data to a&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// socket. It would normally use a series of write() calls. The socket is&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// blocking.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// ssize_t write_data(int fd, uint8_t *data, size_t len) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; struct iovec[3] iov;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; const unsigned n = obstcp_server_encrypt(ctx, data, data, len, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; switch (obstcp_server_ends(ctx, &amp;amp;iovec[0], &amp;amp;iovec[2])) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; case -1:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; abort();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; case 0:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return write(fd, data, n);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; default:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; iovec[1].iov_base = data;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; iovec[1].iov_len = n;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return writev(fd, iovec, 3);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Note that, for non-blocking sockets it's up to the application to deal with&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// feeding the data to the socket. However, obstcp_server_ends may be called&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// repeatedly to get the same data.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// This library doesn't perform writing as such, instead call this function to&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// encrypt the data in preparation for writing.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// output: encrypted data is written here (maybe equal to @buffer)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// buffer: data to be encrypted&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// len: the length, in bytes, of @buffer and @output.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// frame_accum: if true, more data is next so don't close out the frame.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: the number of bytes encrypted&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// A frame can cover, at most, 16384 bytes, so if you repeatedly call this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// function with frame_accum true it may return less than @len bytes to denote&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// that the frame is full.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// NB that the peer cannot process anything until a frame's worth of data has&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// been processed. Thus, if this is the end of a message, and you expect the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// client to answer you, you must close out the frame.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Before writing anything to a socket you must call obstcp_server_ends to get&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// the prepended and appended data for the frame.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;ssize_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_encrypt(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*output, &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*buffer, &lt;span style="color: blue;"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;len,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;frame_accum);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// The protocol may need to prepend and append data to a frame. Call this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// function to get that data. You pass it two iovec's: one to be sent at the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// beginning of the frame and one to be sent at the end.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: -1 on error, or the number of iovecs with data.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// If this function returns -1 it means there has been a programming error on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// the part of the library user. Either you haven't closed out a frame or you&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// haven't opened one. Aborting the process is reasonable in this case.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Note that some connections may not having framing, thus this function may&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// return 0. It's worth detecting this and falling back to a simple write()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// rather than a writev() in this case.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ends(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_server_ctx *ctx, &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;iovec *start,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;iovec *end);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Client interfaces...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;buffer[&lt;span style="color: #00cd00;"&gt;386&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;n;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_half_connection in;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_half_connection out;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;state;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;ssize_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;frame_size;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;frame_open;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// keys: a keyset for the client. Only the default key will be uesd.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// advert: a base64-encoded advert for the server. This can be obtained via TXT&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&amp;nbsp;&amp;nbsp; records in DNS or any other side channel.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// len: length of @advert, in bytes.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// random: 16 random bytes, never to be reused&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// returns: 1 on success, 0 on failure (in which case errno is set)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Obviously, the advert can fail to parse, in which case errno is set to&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// EINVAL.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx_init(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx *ctx, &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_keys *keys,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*advert, &lt;span style="color: blue;"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/span&gt;&amp;nbsp;len,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*random);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// After connecting the socket you must call this function to get the banner&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// that is to be sent to the server. This function must be called exactly once.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// To do otherwise will trigger an assertion failure. The banner returned in&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// the iovec must be completed enqueued to the kernel's socket buffer before&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// doing anything else with this context object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_banner(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;iovec *out);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Same as the server version&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;ssize_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_read(&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;fd, &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*buffer, &lt;span style="color: blue;"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;len, &lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*ready);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Same as the server version&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;ssize_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_encrypt(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx *ctx,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*output, &lt;span style="color: blue;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;uint8_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*buffer, &lt;span style="color: blue;"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/span&gt;&amp;nbsp;len,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;&amp;nbsp;frame_accum);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// Same as the server version&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ends(&lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;obstcp_client_ctx *ctx, &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;iovec *start,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt;&amp;nbsp;iovec *end);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ee0000;"&gt;// -----------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #cd00cd;"&gt;#endif&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ee0000;"&gt;// LIBOBSTCP_H&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-6100916880848095260?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/6100916880848095260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=6100916880848095260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6100916880848095260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6100916880848095260'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/ive-written-new-libobstcp-its-not-in.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-380305303512566622</id><published>2008-08-19T22:00:00.000-07:00</published><updated>2008-08-19T22:51:14.730-07:00</updated><title type='text'></title><content type='html'>The current state of play:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I've made &lt;a href="http://code.google.com/p/curve25519-donna"&gt;curve25519-donna&lt;/a&gt; constant time, and, at the request of DJB, I'll be making it public domain too. I've been told that a group has it working in 165us and I just can't even get close to that. I spent a day rewriting the field multiplication using SSE2, but that didn't help at all. Nevermind, that group aren't releasing their source it seems so they don't count :)&lt;/li&gt;&lt;li&gt;I'm working on getting djbdns's client library in a useful state in order to integrate into Firefox. (did you know that libresolv doesn't parse DNS packets for you? How useless!) So I spent today reviewing 1000s of lines of DJB's code and adding comments.&lt;/li&gt;&lt;/ol&gt;The point of (2) is that my current plans are revolving around these ideas:&lt;br /&gt;&lt;br /&gt;Keeping the server's public key in a &lt;span style=";font-family:&amp;quot;;" &gt;TXT&lt;/span&gt; record for &lt;span style=";font-family:&amp;quot;;" &gt;_obs_80.example.com&lt;/span&gt;. Why &lt;span style=";font-family:&amp;quot;;" &gt;TXT&lt;/span&gt;? Because it's better supported. Thus clients will need a real resolver library, hence my work on DJB's code.&lt;br /&gt;&lt;br /&gt;However, this presents some problems, mostly in the face of transproxies: If we were to connect and write a NUL (to escape HTTP) and then start with encrypting the usual HTTP stream, a transproxy will probably barf. But users can't get around them! (I need to test this with Squid tomorrow).&lt;br /&gt;&lt;br /&gt;So one solution is for the &lt;span style=";font-family:&amp;quot;;" &gt;TXT&lt;/span&gt; record to be able to indicate a separate port number. However, a separate port is a real pain for some sites to setup. So we might need something different. I think that might be encapsulation like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;HEAD / HTTP/1.1&lt;br /&gt;Host: example.com&lt;br /&gt;X-ObsReq: a4bfdz33456sdfFdsFA...&lt;br /&gt;X-TransProxyDetect: flowers&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style=";font-family:&amp;quot;;" &gt;X-ObsReq&lt;/span&gt; carries the encrypted request, so that we don't burn a RTT on the probe. The hope is that transproxies will remove the header that they don't understand (again, have to test with Squid). The server recognises the headers and replies with an encrypted reply in the expected case. However, if a transproxy removed the header, it sends a normal reply. Thus the client can detect the proxy and back off (sadly, probably &lt;i&gt;forever&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;Also, is the &lt;span style=";font-family:&amp;quot;;" &gt;TXT&lt;/span&gt; requirement too much for some? Do we need cross session state as well to get the server keys to the client? (The idea here being that a server can advertise it's keys in an unencrypted reply and the client caches the key, on disk, for some time.)&lt;br /&gt;&lt;br /&gt;Again, it's much more messy furthur up the stack, although we don't need kernel changes.&lt;br /&gt;&lt;br /&gt;Comments welcome. Email or comments on the post.&lt;br /&gt;&lt;br /&gt;(&lt;span style="font-style: italic;"&gt;updated&lt;/span&gt;: before I go to sleep, it strikes me that a series of &lt;span style="font-family: courier new;"&gt;POST&lt;/span&gt;s with uncachable replies may work better)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-380305303512566622?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/380305303512566622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=380305303512566622' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/380305303512566622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/380305303512566622'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/current-state-of-play-ive-made.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-1649653376269307173</id><published>2008-08-15T11:07:00.000-07:00</published><updated>2008-08-15T11:38:28.942-07:00</updated><title type='text'>Sorry folks, I think Obfuscated TCP died</title><content type='html'>Introduction: "Obfuscated TCP is a backwards-compatible modification to the TCP protocol which adds opportunistic encryption. It's designed to hamper and detect large-scale wiretapping and corruption of TCP traffic on the Internet" [&lt;a href="http://code.google.com/p/obstcp"&gt;1&lt;/a&gt;]. &lt;br /&gt;&lt;br /&gt;I'm afraid that the IETF wouldn't go for it. You can see the &lt;a href="http://www.ietf.org/mail-archive/web/tcpm/current/maillist.html"&gt;mailing list archives&lt;/a&gt; if you wish, but it's a lot of email.&lt;br /&gt;&lt;br /&gt;In short, I requested an option in order to use as a switch at the application layer. (Thus, you would still be able to connect to an HTTP server and it could upgrade transparently.) This, it was felt, was a laying violation and the working group members didn't feel there was sufficient motivation to allow it.&lt;br /&gt;&lt;br /&gt;Of course, I'm saddened that they didn't agree. I'm also a little relieved that it's done one way or another. Dealing with defending the draft morning, noon and night for days on end was shockingly draining.&lt;br /&gt;&lt;br /&gt;Obfuscated TCP might regenerate, Time Lord like, but it will end up in a very different form if it does. Below is a list of possible futures. To be more complete, it includes options that I've already decided against. Also, it's in some sort of order, worse first. You'll also note that some of these are sacrificing the original, TCP wide goals for a specific HTTP target.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Ignore the IETF and just take the option number.&lt;/b&gt; This is a really nasty thing to do. I could probably do it, at least as far as getting the patch into the Linux mainline, but it would really hurt the chances of future adoption and the IETF would be mad at me.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Stuff the needed extensions in somewhere else in the header.&lt;/b&gt; This is possible, if icky. A SYN frame typically has 8 bytes unused (the ACK and the timestamp echo). The SYNACK is more troublesome, but I might be able to find somewhere. It would be a painful hack.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Go back to the first design: long options and all in kernel.&lt;/b&gt; Long options requires IETF permission again and I've already been bitten by that. Also, it's known that there's little support in the IETF for long options. Additionally, putting all the crypto in kernel is a nasty wort on the TCP stack. This was a bad design which I dismissed early on; it's still a bad design.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt; Concurrent SYNs.&lt;/b&gt; (Idea from Joe Touch) define a new default HTTP port and have web browsers race two connection opens, one to each port. If the old and the new both come back, close the old. I feel this is fairly ugly, probabilistic and wasteful.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Burn a round trip.&lt;/b&gt; This is the general advice of the IETF. It's also the TLS upgrade method suggested in &lt;a href="http://www.faqs.org/rfcs/rfc2817.html"&gt;RFC2817&lt;/a&gt; (which went nowhere). The problem is that, if browsers started deploying this, it would cost a round trip everywhere. Amazon, Google etc would go balistic because they know how much latency matters. IETF members, sadly, don't. I, personally, couldn't support this.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Exploit connection history.&lt;/b&gt; The idea would be that browsers connect to a new site as they do now, but HTTP headers can advertise support. Then, for future connections to the same site, the browser can optimistically try an obfuscated request, wrapped in HTTP such that it only costs a RTT in the (hopefully rare) case that the optimism was unfounded. Problems here are that the interaction with pipelining is complicated, it's ugly and it doesn't work will with incremental deployment for a single site (if you have many servers). It doesn't, however, require TCP changes. Of anything, this seems like the least bad.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I'm going to take a few days to think about it. Comments are welcome: agl AT imperialviolet DOT org.&lt;br /&gt;&lt;br /&gt;Special thanks also go to Dave McBride for his support of the project thus far. Also to my &lt;a href="http://www.google.com/"&gt;generous employer&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-1649653376269307173?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/1649653376269307173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=1649653376269307173' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1649653376269307173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1649653376269307173'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/sorry-folks-i-think-obfuscated-tcp-died.html' title='Sorry folks, I think Obfuscated TCP died'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-3245819196605944728</id><published>2008-08-13T14:05:00.001-07:00</published><updated>2008-08-13T14:05:47.457-07:00</updated><title type='text'></title><content type='html'>The aforementioned &lt;a href="http://cr.yp.to/ecdh.html"&gt;curve25519&lt;/a&gt; implementation has been &lt;a href="http://code.google.com/p/curve25519-donna"&gt;released&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-3245819196605944728?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/3245819196605944728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=3245819196605944728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3245819196605944728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3245819196605944728'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/aforementioned-curve25519.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-6240031684989660941</id><published>2008-08-05T17:18:00.000-07:00</published><updated>2008-08-05T17:20:30.699-07:00</updated><title type='text'></title><content type='html'>I promised a new release of libobstcp today, but it's not going to happen I'm afraid - maybe Thursday. However, you do get a new draft: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ietf.org/internet-drafts/draft-agl-tcpm-sadata-01.txt"&gt;http://www.ietf.org/internet-drafts/draft-agl-tcpm-sadata-01.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also, I've written an x86-64 version of &lt;a href="http://cr.yp.to/ecdh.html"&gt;curve25519&lt;/a&gt;. Previously, I had a C version that was under half the speed of djb's version. But djb's version was written in 32-bit asm, meaning that it couldn't link with 64-bit code. My 64-bit version is about 10% faster than djb's version. Source code coming soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-6240031684989660941?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/6240031684989660941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=6240031684989660941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6240031684989660941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/6240031684989660941'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/i-promised-new-release-of-libobstcp.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-2909000516549712881</id><published>2008-08-01T13:50:00.000-07:00</published><updated>2008-08-01T13:54:35.988-07:00</updated><title type='text'></title><content type='html'>Things only &lt;i&gt;appear&lt;/i&gt; to be quiet. In the backgroud, I've been madly working on TCP AO support, a new SYNACK payloads draft, getting design reviews etc.&lt;br /&gt;&lt;br /&gt;And a thanks is in order to Dave McBride for being the only person (as far as I know) to actually test the epsilon1 release!&lt;br /&gt;&lt;br /&gt;The plan, currently, is to move ahead with TCP AO support because the IETF draft isn't ready yet. The code is in libobstcp, but #ifdef'ed out.&lt;br /&gt;&lt;br /&gt;So I'll be working on a smaller patch for 2.6.26 which just implements SYNACK payloads. The major blocking factor at the moment is getting the IETF to assign an options number.&lt;br /&gt;&lt;br /&gt;The new draft and patch should be out Tuesday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-2909000516549712881?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/2909000516549712881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=2909000516549712881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2909000516549712881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2909000516549712881'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/08/things-only-appear-to-be-quiet.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-3691102542956551061</id><published>2008-07-23T11:31:00.000-07:00</published><updated>2008-07-23T11:33:54.660-07:00</updated><title type='text'>First testing release</title><content type='html'>I've just put up the first testing release, which I'm not even calling an alpha:&lt;br /&gt;&lt;a href="http://code.google.com/p/obstcp/wiki/Testing"&gt;http://code.google.com/p/obstcp/wiki/Testing&lt;/a&gt;. If you can patch and build a kernel, please try it out. I'll be hanging out on #obstcp on OFTC.net today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-3691102542956551061?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/3691102542956551061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=3691102542956551061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3691102542956551061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3691102542956551061'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/first-testing-release.html' title='First testing release'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-5773300106530023642</id><published>2008-07-18T17:23:00.000-07:00</published><updated>2008-07-18T17:25:39.410-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.ietf.org/internet-drafts/draft-ietf-tcpm-tcp-auth-opt-01.txt%20"&gt;TCP-AO&lt;/a&gt; experimental &lt;a href="http://www.spinics.net/lists/netdev/msg69416.html"&gt;patches&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-5773300106530023642?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/5773300106530023642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=5773300106530023642' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5773300106530023642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5773300106530023642'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/tcp-ao-experimental-patches.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-1489051674275372482</id><published>2008-07-15T13:00:00.000-07:00</published><updated>2008-07-15T13:01:16.255-07:00</updated><title type='text'></title><content type='html'>&lt;div class="separator" style="text-align: center; clear: both;"&gt;&lt;a href="http://bp3.blogger.com/_kRcqvZJgJFs/SH0B_oPSlzI/AAAAAAAAAUM/eg-IxgbyhIs/s1600-h/firefox-obstcp.png" imageanchor="1" style="border: 0pt none ; background-color: transparent; margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="http://bp3.blogger.com/_kRcqvZJgJFs/SH0B_oPSlzI/AAAAAAAAAUM/fm6pyt7mRkI/s400-R/firefox-obstcp.png" style="border: 0pt none ;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-1489051674275372482?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/1489051674275372482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=1489051674275372482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1489051674275372482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1489051674275372482'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/blog-post.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_kRcqvZJgJFs/SH0B_oPSlzI/AAAAAAAAAUM/fm6pyt7mRkI/s72-Rc/firefox-obstcp.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-1344508727380505001</id><published>2008-07-11T17:18:00.000-07:00</published><updated>2008-07-11T17:22:28.935-07:00</updated><title type='text'></title><content type='html'>Today:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The userspace &lt;span style="font-family: courier new;"&gt;libobstcp&lt;/span&gt; is looking good. Current source is checked into the svn (&lt;a href="http://code.google.com/p/obstcp"&gt;http://code.google.com/p/obstcp&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Patched &lt;span style="font-family: courier new;"&gt;lighttpd&lt;/span&gt; to use &lt;span style="font-family: courier new;"&gt;libobstcp&lt;/span&gt; - pretty easy, although I cheated a little by patching its &lt;span style="font-family: courier new;"&gt;writev&lt;/span&gt; backend rather than the (more complex) aio-sendfile one.&lt;/li&gt;&lt;li&gt;Patched &lt;span style="font-family: courier new;"&gt;libevent&lt;/span&gt;'s httpd to use &lt;span style="font-family: courier new;"&gt;libobstcp&lt;/span&gt; and wrote a very simple webserver using it which echos the obfuscation state of the connection&lt;/li&gt;&lt;li&gt;Finished up the SYNACK payload draft (for now, there will be changes in the future) - see last post&lt;/li&gt;&lt;li&gt;Working on setting up a firefox build so that I can patch libobstcp into Firefox. That'll be quite a task&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-1344508727380505001?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/1344508727380505001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=1344508727380505001' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1344508727380505001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1344508727380505001'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/today-userspace-libobstcp-is-looking.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-7386345595470877677</id><published>2008-07-11T10:57:00.000-07:00</published><updated>2008-07-11T11:00:37.202-07:00</updated><title type='text'></title><content type='html'>New draft: &lt;a href="http://www.imperialviolet.org/binary/draft-agl-tcpm-sadata-00.html"&gt;draft-agl-tcpm-sadata-00&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;That draft specifies the stack changes to enable the current, mostly userspace, ObsTCP. My experimental version of the kernel patch comes in at just 150 lines of additional code. Also, it's currently working between my laptop and my home computer through two NATs. The major omission, currently, is that the packets aren't signed. I'm hoping that TCP-AO will take care of that at some point in the future. For now, I'm moving ahead with encryption only.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-7386345595470877677?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/7386345595470877677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=7386345595470877677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/7386345595470877677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/7386345595470877677'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/new-draft-draft-agl-tcpm-sadata-00-that.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-1178956763462490905</id><published>2008-07-08T16:54:00.000-07:00</published><updated>2008-07-08T16:58:10.888-07:00</updated><title type='text'></title><content type='html'>I like header files which tell you everything you need to know about the library. Here's the &lt;span style="font-family: courier new;"&gt;libobstcp&lt;/span&gt; one:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// Perform global setup. This must be called exactly once for a given process.                                                                                &lt;br /&gt;//&lt;br /&gt;// private_key: If non-NULL, this must be a 32-byte private key. Otherwise, the                                                                               &lt;br /&gt;//   private key is taken from /dev/urandom. The private key is free form                                                                                     &lt;br /&gt;//   random data. It will be tweaked to be a valid private key.&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;void obstcp_init(const void *private_key);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// Write the current private key to the given buffer. Note that the private key                                                                               &lt;br /&gt;// may not be exactly equal to the private key given to obstcp_init because not&lt;br /&gt;// every random string is a valid private key.&lt;br /&gt;//&lt;br /&gt;// private_key: a 32-byte buffer&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;void obstcp_private_key_get(void *private_key);                                                                                                               &lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// Write the current public key to the given buffer                                                                                                           &lt;br /&gt;//&lt;br /&gt;// public_key: a 32-byte buffer&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;void obstcp_public_key_get(void *public_key);                                                                                                                 &lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// For a client connection:                                                                                                                                   &lt;br /&gt;//   * Create an obstcp_ctx object, either on the stack or on the heap. This&lt;br /&gt;//     must persist for the length of the connection.                                                                                                         &lt;br /&gt;//   * Call obstcp_ctx_init_client with a socket, before connect()ing the&lt;br /&gt;//     socket&lt;br /&gt;//   * You must complete key exchange before the server can write to you.                                                                                     &lt;br /&gt;//     This involves writing a small amount of data. If you use obstcp_write,                                                                                 &lt;br /&gt;//     it will happen automatically. Otherwise you can call obstcp_kx_write to                                                                                &lt;br /&gt;//     write the data. Once the kernel has accepted the data,&lt;br /&gt;//     obstcp_kx_complete will return non-zero.&lt;br /&gt;//   * Then use obstcp_read and obstcp_write just as you would use read and                                                                                   &lt;br /&gt;//     write. If the server doesn't support obfuscation, these are just pass                                                                                  &lt;br /&gt;//     through functions.&lt;br /&gt;//&lt;br /&gt;// For a server connection:                                                                                                                                   &lt;br /&gt;//   * Create and bind a socket                                                                                                                               &lt;br /&gt;//   * Call obstcp_setup_listening on the socket.                                                                                                             &lt;br /&gt;//   * Accept a connection.&lt;br /&gt;//   * Create an obstcp_ctx object, either on the stack or on the heap. This                                                                                  &lt;br /&gt;//     must persist for the length of the connection.                                                                                                         &lt;br /&gt;//   * Call obstcp_ctx_init_server on the *accepted* socket.&lt;br /&gt;//   * Use obstcp_read and obstcp_write as you would use read and write. If                                                                                   &lt;br /&gt;//     anything was unsupported or failed, these will just work in pass through                                                                               &lt;br /&gt;//     mode.&lt;br /&gt;// -----------------------------------------------------------------------------    &lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// The per-connection state.                                                                                                                                  &lt;br /&gt;//&lt;br /&gt;// Multithreading: no two threads can be using the same obstcp_ctx at the same                                                                                &lt;br /&gt;// time. It's up to the user to ensure this.                                                                                                                  &lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;struct obstcp_ctx {&lt;br /&gt;  uint8_t  state;&lt;br /&gt;  uint8_t  reason;&lt;br /&gt; &lt;br /&gt;  uint32_t input[16];                                                                                                                                         &lt;br /&gt;                                                                                                                                                              &lt;br /&gt;  uint8_t  in_keystream[128];                                                                                                                                 &lt;br /&gt;  unsigned in_used;                                                                                                                                           &lt;br /&gt;  uint64_t in_seq;&lt;br /&gt; &lt;br /&gt;  uint8_t  out_keystream[128];                                                                                                                                &lt;br /&gt;  unsigned out_used;                                                                                                                                          &lt;br /&gt;  uint64_t out_seq;&lt;br /&gt;};&lt;br /&gt; &lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// Setup a socket (after bind, but before listen) to enable obfuscation.                                                                                      &lt;br /&gt;//&lt;br /&gt;// Returns: non-zero if the kernel doesn't support obsfuscation. You can ignore                                                                               &lt;br /&gt;//   this because everything else will drop into pass through mode in this                                                                                    &lt;br /&gt;//   case.&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;char obstcp_setup_listening(int fd);                                                                                                                          &lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------                                                                              &lt;br /&gt;// Setup a context structure to start processing a new connection.                                                                                            &lt;br /&gt;//&lt;br /&gt;// fd: a file descriptor to a TCP socket, freshly accepted.&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;void obstcp_ctx_init_client(struct obstcp_ctx *ctx, int fd);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// Setup a server socket (after bind, but before listen) to support&lt;br /&gt;// obfuscation.&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;void obstcp_ctx_init_server(struct obstcp_ctx *ctx, int fd);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// Read from the given file descriptor and decrypt. Note that, at the beginning&lt;br /&gt;// of the connection, this function may return -1 and set errno to EAGAIN to&lt;br /&gt;// reflect the fact that some network data is consumed by key setup. All other&lt;br /&gt;// behaviour matches read(2).&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;ssize_t obstcp_read(struct obstcp_ctx *ctx, int fd, void *buf, size_t count);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// Encrypt the data to a buffer on the stack and write to the network. All&lt;br /&gt;// other behaviour matches write(2)&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;ssize_t obstcp_write(struct obstcp_ctx *ctx, int fd, const void *buf,&lt;br /&gt;                     size_t count);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// If obstcp_kx_complete returns zero, we still need to write data to complete&lt;br /&gt;// the key exchange. To write as much as possible, call this function.&lt;br /&gt;// Afterwards one can call obstcp_kx_complete to see if the exchange is&lt;br /&gt;// complete.&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;void obstcp_kx_write(int fd, struct obstcp_ctx *ctx);&lt;br /&gt;&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// Return non-zero iff key exchange has completed, or failed. Either way, the&lt;br /&gt;// host doesn't need to read/write any more data for key exchange.&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;char obstcp_kx_complete(const struct obstcp_ctx *ctx);&lt;br /&gt;&lt;br /&gt;#define OBSTCP_NOT_ESTABLISHED  0&lt;br /&gt;#define OBSTCP_MAYBE            1&lt;br /&gt;#define OBSTCP_ESTABLISHED      2&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// Return if obfuscation is active on the given connection.&lt;br /&gt;//&lt;br /&gt;// Returns:&lt;br /&gt;//   OBSTCP_NOT_ESTABLISHED: Connection is pass through mode. Call&lt;br /&gt;//     obstcp_failure_reason to find out why&lt;br /&gt;//   OBSTCP_MAYBE: (client side) Key exchange hasn't completed yet.&lt;br /&gt;//   OBSTCP_ESTABLISHED: Key exchange complete. The connection will be&lt;br /&gt;//     obfuscated&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;char obstcp_established(const struct obstcp_ctx *ctx);&lt;br /&gt;&lt;br /&gt;#define OBSTCP_NO_KERNEL        0&lt;br /&gt;#define OBSTCP_NOT_OFFERED      1&lt;br /&gt;#define OBSTCP_KX_FAILURE       2&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;// If obstcp_established returned OBSTCP_NOT_ESTABLISHED, then one can call&lt;br /&gt;// this function to find out what went wrong.&lt;br /&gt;//&lt;br /&gt;// Returns:&lt;br /&gt;//   OBSTCP_NO_KERNEL: The kernel doesn't support obfuscation&lt;br /&gt;//   OBSTCP_NOT_OFFERED: (server side) client didn't request obfuscation&lt;br /&gt;//   OBSTCP_KX_FAILURE: key exchange failed (protocol error)&lt;br /&gt;// -----------------------------------------------------------------------------&lt;br /&gt;char obstcp_failure_reason(const struct obstcp_ctx *ctx);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-1178956763462490905?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/1178956763462490905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=1178956763462490905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1178956763462490905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/1178956763462490905'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/i-like-header-files-which-tell-you.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-2238729610332599609</id><published>2008-07-08T11:05:00.000-07:00</published><updated>2008-07-08T11:18:51.329-07:00</updated><title type='text'>A small change in direction</title><content type='html'>I now believe that I was previously too quixotic about getting changes into TCP and I'm exploring a different approach for now. Previously, the kernel handled almost everything: key exchange (using long options), encryption and signing. Now I'm leaning towards a setup where the kernel provides a generic way to include a payload in SYNACK packets. This turns up in normal read() calls in userspace (if userspace has requested it). Now, the key exchange can be performed in userspace, as can the encryption &lt;i&gt;and&lt;/i&gt; we end up with less TCP changes.Signing still needs to be performed in the kernel, however, as it needs to protect the whole packet (to stop RST attacks etc). For this, I'm hoping that the TCP-AO standard (which replaces TCP MD5) will suffice. Sadly, the TCP-AO draft authors are being very quiet.All in all, I don't expect a lot of movement until the fall IETF meeting, which I hope to attend.There will be kernel patches before then, however.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-2238729610332599609?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/2238729610332599609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=2238729610332599609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2238729610332599609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2238729610332599609'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/small-change-in-direction.html' title='A small change in direction'/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-5880993049498129127</id><published>2008-07-01T10:14:00.000-07:00</published><updated>2008-07-01T10:15:01.546-07:00</updated><title type='text'></title><content type='html'>Long options submitted to TCPM working group of the IETF for discussion:&lt;br /&gt;&lt;a href="http://www.ietf.org/mail-archive/web/tcpm/current/msg03677.html"&gt;http://www.ietf.org/mail-archive/web/tcpm/current/msg03677.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-5880993049498129127?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/5880993049498129127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=5880993049498129127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5880993049498129127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/5880993049498129127'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/07/long-options-submitted-to-tcpm-working.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-7171123736006008064</id><published>2008-06-27T11:08:00.001-07:00</published><updated>2008-06-27T11:08:54.284-07:00</updated><title type='text'></title><content type='html'>New draft replaces the old Jumbo options draft that I did:  &lt;a href="http://www.imperialviolet.org/binary/draft-eddy-tcp-loo-04.html"&gt;draft-eddy-tcp-loo-04.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-7171123736006008064?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/7171123736006008064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=7171123736006008064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/7171123736006008064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/7171123736006008064'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/06/new-draft-replaces-old-jumbo-options.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-2895154950369214362</id><published>2008-06-24T16:37:00.000-07:00</published><updated>2008-06-24T16:39:40.733-07:00</updated><title type='text'></title><content type='html'>I've posted some of the new patches to netdev - the kernel mailing list for such things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://marc.info/?l=linux-netdev&amp;amp;m=121426260509452&amp;amp;w=2"&gt;TCP options clean up&lt;/a&gt;&lt;b&gt;&lt;span style="font-size:+1;"&gt;&lt;span style="font-family: monospace;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size:+1;"&gt;&lt;span style="font-family: monospace;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;a href="http://marc.info/?l=linux-netdev&amp;amp;m=121434882711824&amp;amp;w=2"&gt;&lt;span style="font-size:100%;"&gt;Remove options logic from SACK calculations in tcp_input.c&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-2895154950369214362?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/2895154950369214362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=2895154950369214362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2895154950369214362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/2895154950369214362'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/06/ive-posted-some-of-new-patches-to.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6269139839497360743.post-3894329954504789852</id><published>2008-06-19T12:57:00.000-07:00</published><updated>2008-06-19T13:00:42.139-07:00</updated><title type='text'></title><content type='html'>More motivation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ArsTechnica: &lt;a href="http://arstechnica.com/news.ars/post/20080619-report-nebuad-ads-inserted-via-man-in-the-middle-attack.html"&gt;NebuAd ads inserted via "man-in-the-middle attack"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://news.bbc.co.uk/2/hi/europe/7463333.stm"&gt;Sweden approves wiretapping law&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6269139839497360743-3894329954504789852?l=obstcp.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://obstcp.blogspot.com/feeds/3894329954504789852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6269139839497360743&amp;postID=3894329954504789852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3894329954504789852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6269139839497360743/posts/default/3894329954504789852'/><link rel='alternate' type='text/html' href='http://obstcp.blogspot.com/2008/06/more-motivation-arstechnica-nebuad-ads.html' title=''/><author><name>Adam Langley</name><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09391162910132900780'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>