Cocoaphony

RNCryptor HMAC Vulnerability (My Security Blunder)

Thank you to Allen Mann for discovering the following significant security vulnerability in RNCryptor.

The Vulnerability

RNCryptor computes the HMAC over the ciphertext only. It does not compute an HMAC over the header, particularly the IV. This allows an attacker to modify the IV and thus manipulate the first block (16-bytes) of decrypted plaintext. This is a major issue, and is exactly the kind of problem that RNCryptor is designed to avoid.

I will be modifying RNCryptor shortly to fix this. This will rev the file version to 2. I will provide a backward-compatibly option to read v1 files (default off). I strongly recommend that developers move to the v2 format.

I will try to get this out as quickly as I can, hopefully this week.

Animating Arbitrary KeyPaths

During CocoaConf-2012-Raleigh, I discussed my PinchView from Laying out text with Core Text. It’s a text view that squeezes the glyphs towards your finger when you touch it. I built it to demonstrate per-glyph layout in Core Text. While demonstrating it, I was pretty unsatisfied with how it looked when you touched it or let go. When you drag your finger on the view, the glyphs move around like water. It’s quite pretty. But when you initially touch the screen, the glyphs suddenly jump to their new locations, and then they jump back when you release the screen. Well, that’s no good. So I wanted to add animations.

But here’s the thing: what do you animate? While you do want to animate the glyph positions, you’re not doing it directly. The location of each glyph is dependent on the location of the current touch. What you want to animate is how much the touch impacts the glyph positions. A quick look over CALayer’s list of animatable properties confirmed that there’s nothing like that. But no problem, I added a custom property called touchPointScale and animated that. (I cover animating custom properties in the Layers chapter of iOS:PTL, and I still have to pull out that chapter every time to remind myself how to do it. Ole Begemann has a good, quick writeup on Stack Overflow.)

RNCryptor and My Titanium Experiment

Several months ago, I received a request to port my RNCryptor module to Titanium. I’ve never been a fan of the JavaScript wrappers for iOS and Android. My belief and experience is that they’re far more trouble than their worth. But the goal of RNCryptor was always to help people use AES correctly, and that’s as important in JavaScript as it is in Objective-C. So I wrapped up RNCyptor into a Titanium module and stuck it on the Appcelerator Marketplace. Though RNCryptor is free, the pain of wrapping it into JavaScript led me to charge $10 for the Titanium version.

The pain of maintaining this thing has gotten to be too much, though. I’m releasing it today on GitHub in its current form, which is based on the older, synchronous form of RNCryptor. I may not have updated all the license text yet; if I miss any, it is under the MIT license. Thanks to those who purchased Cryptor-Titanium during its commercial life. Anyone who is interested in continuing development, please contact me (or submit a pull request).

Updated RNCryptor

I have brought the RNCryptor async branch to master. This is a major change in API, but I believe much more flexible. I’ve stripped the API down quite a lot, so please let me know if there are missing features. I’m particularly interested in anyone who needs better support for reading and writing files. I haven’t added any methods for that until I see how people are really using it.

Phone-screening Cocoa Developers

There was an interesting question on StackOverflow that was unfortunately closed as off topic. It was off topic, but it’s still a useful question. When phone screening potential Cocoa developers, what kinds of questions should you ask? I’ve helped several clients screen potential candidates over the years, and so I have several questions I use to help with that.

RNCryptor Async

I have completed the major work for RNCryptor asynchronous operations on the async branch. This changes the API and the file format. I’ll be documenting this more formally within a few weeks, but here are the high points:

Mode Changes for RNCryptor

After several feature requests, much consideration, and a long chat with the security engineering team at Apple, I’ve decided to make a change to the default AES mode used by RNCryptor from its current CTR to the much more ubiquitous CBC.

CTR mode has several advantages that I was hoping to exploit. First, it does not require padding, so it is not subject to padding oracle attacks (the cipher text is also generally a few bytes shorter than the equivalent CBC). That said, if the same nonce+counter+key combination is ever reused, an attacker can easily compute the key. This is pretty unlikely given how RNCryptor generates its nonce, but it’s not impossible. If the same IV+key is used for CBC mode, then some information is leaked to an attacker, but its not nearly as catastrophic as reusing a nonce. The point is that CTR is not a home run here. It’s different, exchanging one possible vulnerability for a different one (since RNCryptor does not store previous nonces to prevent reuse).

It is also possible to compute CTR in parallel on multiple cores. Apple doesn’t currently do this, and is not highly likely to do so in the future. They might, but it’s not something to adapt the design to.

Almost every AES system out there implements CBC, so using any other mode introduces a significant interoperability problem. A mode would need to be dramatically better to be worth that. CTR has not lived up to that requirement, and so I’m switching to CBC.

This will make it much easier to write RNCryptor-compatible modules in Java, JavaScript, etc., as have been requested.

Possibly most importantly, this change gets us closer to making RNCryptor compatible back to iOS 4.0, and Mac OS X 10.4. I still have to consider CCKeyDerivationPBKDF.

If you update, note that this is incompatible with your existing encrypted files. I doubt there is enough field usage out there that this is an issue, but if it is, let me know and I can discuss with you how to convert.

Simple GCD Timer (RNTimer)

I know this exists out there somewhere already, but I couldn’t find it anywhere and I was sick of writing it over and over again…. If someone knows of previous art, please point me in the right direction. I know Fiery Robot’s and Mike Ash’s, but they solve different problems.

Have you ever noticed how hard it is to write a repeating NSTimer that doesn’t create a retain loop? Almost always you wind up with something like this:

[NSTimer scheduledTimerWithTimeInterval:1
                                 target:self
                               selector:@selector(something)
                               userInfo:nil 
                                repeats:YES];

Seems easy enough, except it’s a retain loop. Mike Ash does a nice job of explaining it and walking you through the hoops you need to avoid it. For such a common thing, you’d think this would be easy. And it should be, so I fixed it. I just still can’t quite believe I’m the first to do so.

Anyway, for your consideration I present a very simple class called RNTimer. Right now it just handles the most common case: a repeating timer that does not generate a retain loop and automatically invalidates when it is released. It could of course be expanded to handle more NSTimer functionality if there is interest. Let me know if you have a use case that the current implementation doesn’t address.

You may find it along with further information at GitHub.