Security: The CommonCrypto library
OS X’s API is full of unsung heroes. While everybody knows about Cocoa and Carbon, and is wowed by the new shinies such as Grand Central Dispatch or Core Animation, other components have been silently and solidly plugging away, forming a basic foundation on which the rest of the system can rest. This article is about one such component.
Buried away in libSystem, the core library on Mac OS X and the iPhone OS, is the CommonCrypto library. This provides a highly-optimised implementation of some basic cryptographic capabilities, used throughout the operating system and available to your applications.
The encryption capabilities provided by CommonCrypto are standard symmetric encryption algorithms. In symmetric encryption, the same key is used both to encrypt the data (known as “clear text”) and to decrypt the encoded data (“cipher text”). The key is therefore shared; both the sender and recipient of the message must know what it is in order for the secret message to be transmitted. Think of the substitution ciphers that children’s books on spies use for hiding secret messages, where every letter in the alphabet is replaced by a different letter to encode a message. By knowing how the message was constructed, you also know what you need to do to recover the clear text from an encrypted message. This type of cipher is therefore symmetric.
Also, a note on encryption algorithms. Unless you happen to be Bruce Schneier, it is never a good idea to write your own algorithm for encrypting data, nor even to roll your own implementation of an existing algorithm. If a vendor tells you they use their own proprietary encryption algorithm then no matter how flashy their marketing material is, you should stay away. The standard algorithms, like the AES and 3DES provided by CommonCrypto, have been carefully scrutinised by hundreds of people for many years. Their capabilities and limitations are well-understood. The same cannot be true of any trade-secret or novel encryption.
Use of CommonCrypto’s symmetric API is described in the manual page for CCCryptor(3). The basic life-cycle of a CCCryptorRef is this:
- create a CCCryptorRef with CCCryptorCreate()
- add data to it with CCCryptorUpdate(), until you have sent all the data
- complete the encryption/decryption with CCCryptorFinal()
- release the CCCryptorRef with CCCryptorRelease()
Notice that although the interface is very similar to a Core Foundation class’s API, CCCryptorRefs are not CFTypeRefs and do not behave as Core Foundation objects.
Another useful feature of CommonCrypto is its HMAC calculation capability. HMAC stands for Hashed Message Authentication Code. By using a shared secret key and a known algorithm, both the sender and recipient of some data can calculate a number based on that data, similar to a checksum. The sender gives the recipient the number they came up with alongside the original data. The recipient re-calculates the code for iteself and compares the two. For the sender’s and recipient’s numbers to agree, both the key and the message must be the same (unless there is a “collision”, though the algorithms are chosen to make this rare). This means that not only is the _integrity_ of the message assured, the _authenticity_ is too. If the recipient calculates the same authentication code as it was sent, then it knows both that the sender was legitimate (or at least, had access to the secret key through some means) and that the message has not been tampered with.
Calculating an HMAC with CommonCrypto is very similar to encrypting with the library, and is described in CCHmac(3).
So the only question remaining is where to put the key? If there are multiple agents dealing with the protected data, whether multiple processes on the same machine or applications on different computers/phones, they must all have access to the same shared secret. For the confidentiality of encrypted data or the authenticity of authenticated data to remain assured, no other agent must have access to the secret. A common technique is to “bake” the key into the application binary, using a #define or const char* variable. This is not such a good idea, because an attacker with a copy of the app can simply look through the binary to find out what the key is. A slightly more obfuscated version of this approach involves building the key from a number of small segments stored in the binary, with -[NSMutableData appendBytes:] or a similar method.
Where possible I would recommend using the keychain to store the shared key, using some out-of-band mechanism (like sneakernet!) to get the same key to different boxes, as long as this is not too complicated or inconvenient for the users. The keychain on an iPhone is protected by a key stored on the device, and a user’s keychain on a Mac is protected by a password (usually the login password). Additionally on a Mac, access controls can be placed to restrict which apps may read any secret from the keychain, and the secrets are not shared between apps at all on the iPhone.
About Graham
Graham Lee is an independent Cocoa security expert in the UK. He can be followed on Twitter as @iamleeg.









Thanks for the article!
“Unless you happen to be Bruce Schneier, it is never a good idea to write your own algorithm for encrypting data.”
And I’m sure Bruce wouldn’t trust an algorithm even if he had written it himself, until his peers had spent years trying to find weaknesses in it.
“The keychain on an iPhone is protected by a key stored on the device”
This strikes me as a weaker link in the security chain than the obfuscated approach you describe?
“and the secrets are not shared between apps at all on the iPhone.”
I believe it’s possible to share secrets between apps with shared identifier prefixes (i.e. from the same vendor).
Good article!
Do you have any thoughts on the relative merits of CommonCrypto and the Crypto++ library at , which until now I’ve preferred for portability reasons?
I’ve found that Crypto++ has a bit of a learning curve, but once you grok it it’s very easy to implement.
I soooo wanted to use CommonCrypto recently … but our maintenance code base is still targetting 10.4 and up, so I had to really look long and hard to find an implementation for an SHA-HMAC that I could use. Looking forward to dumping that code!
@hatfinch: I thought the same about the iPhone device key when I first found out. However the key can’t be extracted from the hardware, it can only be used to unlock the keychain. That means the keychain contents can’t be read from the iPhone filesystem backup in iTunes. Due to the access controls which stop one iPhone app reading the keychain entries of another app, there are only two ways remaining for someone who controls my iPhone to make use of my keychain items:
- use the phone; the PIN protection should make that unlikely
- jailbreak it; a level of technical and time investment beyond many attacks.
@RichardB: I haven’t used Crypto++, my C++-fu is not that strong. It certainly seems to have a wider set of capabilities than CommonCrypto.
[...] If you’ve changed the number, use your new number instead of 31313. Mac Developer Network » Blog Archive » Security: The CommonCrypto … [...]
Leave your response!
Donate to MDN
Shopping Cart
Log In
Join
Lost your Password?
Feeds
The MDN ShowAll of the old episodes of the old shows can be found on The MDN Show Feed
The MDN BIG BLOG
To subscribe to the BIG BLOG point your RSS reader at http://feeds.feedburner.com/mdnbigblog
Categories