Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-212
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 212
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 212] Next Genera...

WWDC11 • Session 212

Next Generation Cryptographic Services

Core OS • OS X • 46:01

Learn about new cryptographic capabilities as well as changes made to the cryptographic services in Mac OS X. Gain insight into the best practices and techniques for using cryptography in your code. Learn how easy it is to add cryptography to your applications.

Speaker: Jon Callas

Unlisted on Apple Developer site

Downloads from Apple

HD Video (146.7 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning everyone. Thank you for coming out early on a Friday, especially after all the partying and so on last night. I'm Jon Callas. I'm a security privateer in CoreOS and I'm going to be talking about the next generation cryptographic services. What we're going to be talking about is the exciting changes that we've made to our cryptographic architecture. This is the first time that we have reworked cryptography in a decade on Mac OS. And the first time that we've done a lot of work on iOS as well.

We're going to be talking about the changes that we've made to the existing APIs. We're going to be spending a lot of time talking about our new transform API. We're going to talk about our transform library and how to create your own custom transforms to build on top of that yourself. So I want to get started off right away talking about CDSA, which is the current cryptographic system. It is the common data security architecture. We are deprecating in Lion CDSA.

There are a number of reasons that we're doing it. It's an open group standard. It dates in its architecture to the late 1990s. It appeared with Mac OS X and was developed through the first couple of releases. Being what it is, it comes from an era in which there was exportable crypto, pluggable this, tunable that. It had lots of features that nobody ever used. Also, one of the reasons why it's good to have standards is that everybody uses them.

And we were one of the very few people who actually used CDSA. So that meant that we had to support all of the baggage of a standard without having the advantage that lots of people were using it. Also, it only ever appeared on Mac OS. It was not brought to iOS. And a lot of the reasons why it wasn't brought to iOS were pretty much the same thing. It was big. It wasn't used very well. So we are deprecating it.

Now, deprecated doesn't mean that it's cancelled. It's still there. It'll still be around for a release or so. Start migrating away from it if you're using it. If you're doing any new projects, Take a serious look at what we're doing now. There are also a few parts of the security framework that had strict dependencies on CDSA. We have deprecated those APIs as well.

If you get a deprecation warning on it, go to the H file. We have put in the H files hints on what you should be using. There will be a number of places as well that merely recompiling will fix things for you because we changed the types around and the new type and the new call itself will all match up correctly.

When we set about working for a new API, we sat down and we came up with requirements. What did we want it to be? Because we want to have a crypto API that is designed for the decades ahead. We want this to be something that will be less code. We want it to be faster. We want it to be faster not only in its operation but in your using it as a programmer. We want it to be able to do concurrency.

While crypto is not really a major problem in any sort of algorithm anymore because CPUs are fast enough, concurrency is a real issue. We're getting more CPUs all the time. There's hardly anything left that we have that has a single CPU in it. And, you know, right now there are laptops with eight CPUs, four cores but eight CPUs.

So concurrency is a really big issue. Also, when you start looking at what crypto is, it's not just a few mathematical algorithms. You know, yeah, it's your ciphers, it's your hash functions, but then you find yourself doing compression as well. You start storing certificates in LDAP databases. You start doing rest calls across the network.

You code things up in XML or JSON and pretty soon crypto starts looking an awful lot like everything else. So we wanted to have a way that you could do secure programming and all of what you need to do no matter what it is. The result of that is our new architecture here. It has common crypto, our new transform API, and the security framework at the top.

Starting with them, Common Crypto is our low-level API. It's basic core algorithms. It's really what you would think of as a crypto toolkit. Its documentation is man pages. It's pretty serious C programming. It's also the foundation that we're going to be doing for our FIPS 140 validations from here on.

Our idea is that if you code common crypto, and that includes our own code that codes to common crypto, then you get to inherit our validations. So we want it to be small, we want it to be tight, we want it to be the real foundation and framework of the rest of the building in an architectural metaphorical sense.

It may not be new to you, Common Crypto existed in Snow Leopard. When we looked at what we wanted for a very low-level API, Common Crypto was sufficiently close to what it was going to have to be no matter what that we said, hey, let's just start working from there.

In Lion, we recoded the internals and we took that recoded Lion Common Crypto and moved it to iOS and did more work on it from there. I'll also note that just this Tuesday, we got all of the NIST algorithm certificates for all of the algorithms in Common Crypto for iOS. So that's not just, oh yes, we want to do FIPS on it. No, really, we're doing FIPS on it.

One of the major advantages you have in using Common Crypto is that you can say, oh, I want to do AES. And Common Crypto knows what hardware you're on and it picks the right AES. If you happen to be on one of the new i5, i7 Intel machines, it will use the AES NI instructions. If you're on an older computer, it will use a vector optimized system. On iOS, we also have vector optimized implementations of several of the algorithms.

Jon Callas The idea is that code here for your raw stuff and we're going to pick the best way for that to run and you don't have to think about it because that's one of the big problems with crypto is how many fiddly bits there are and we're going to select the right fiddly bits for you.

At the very top, we have the security framework. It is a core foundation based API. As I said before, we've deprecated the parts that were dependent upon CDSA. There are corresponding ones that have been replaced what's there or we migrated the data types directly for you. And that has keychains, trust models, certificate processing, things like that. It also has some relatively high-level APIs, which I'll show you a little bit more about later.

Now in the middle, there's transforms and they're brand new and they're built on Grand Central Dispatch. Grand Central Dispatch is incredible. If you haven't been using it, you need to. Just about everything that we're doing going forward revolves around blocks, revolves around Grand Central Dispatch. Jon Callas Grand Central Dispatch makes it so that when you are writing threaded code, you don't have to think about the threads. You think about work units, you think about queues, and that's all you have to do.

Jon Callas What we did with transforms was that we took Grand Central Dispatch and turned it into a data flow architecture. So when you use transforms, you think about... Parts of the data and steps that it goes through to go through whatever you want. The advantage of this is that it looks a lot like a generic function because you can have an encrypt transform that does the right sorts of encryption based upon the parameters and whatever the parameters are, it just does the right thing. I have an example that will make that a little more clear later.

It's also a general purpose concurrency mechanism. Anything that you have that has work that can be broken up into small things works with transforms. Now to get to the gotchas on this, Transforms are only Lion, they are not yet iOS. Common Crypto is in both Lion and iOS, and as I said, the iOS version is in fact a successor to the Lion version.

Normally when we give new APIs, we like to have the full thing in place when we do deprecation of an old one. We didn't do that this time. And the reason that we didn't do that is we're really pleased with what we've done. We want you to have it and work with it and tell us what you need before we have everything in place because it really is very nice and the other one was kind of old. Jon Callas So the major parts that are really missing are some certificate handling details. There are other rough edges.

Please tell us on bugreporter.apple.com. You're going to hear me say that a lot. Tell us what you need. We schedule everything that we do based upon what's in Bug Reporter. Jon Callas And if you tell us what's there, even if it's a duplicate of what other people have told, so don't think, oh, somebody else has probably said this. Jon Callas If five people tell us this, and three people tell us that, it gives us more support in figuring out what gets done before something else.

So let me go on and talk more about transforms. Transforms are all about taking small changes and putting them together. It's not just for crypto. It's for any sort of sequential processing. You could, for example, use transforms to take two different RSS feeds and combine them together into a mashup. You could do something else like code optimization. You know, code optimizers work by having little things that each know a few things all stream through a code, modifying as it goes on. These are all the sorts of workflows that work well for transforms.

To give you a quick non-crypto example, let's imagine that we want to do a mashup. And we want to do a mashup where we want to take cat videos and we want to take earthquake videos and we want to mash them up together. You're going to have a transform that goes out and finds cats.

You're going to have a transform that goes out and finds earthquakes. They each run in parallel. And then a third transform that combines them together and there you have your mashup. And that's the sort of idea that we have of things run in parallel and things run in small changes where you don't have to think about the entire thing in the part that you have.

I'll give you a few analogies on this. My usual one and favorite one is these are like Unix pipelines. If you've ever done any sort of shell programming, you know, you sort, you grep, you TR, you awk, you do these things and you pipe them all together. Transforms are really a lot like that.

They're small units that work together to give you a bigger whole. The major differences are that they revolve around data chunks, core foundation, not bytes. You know, Unix programming is, it's all bytes. These things are all routines rather than processes. Okay, really they're blocks, but you know, blocks are just routines with frosting and sprinkles.

And when you do transforms, it's really easy to have multiple gazintas and multiple gozaudas. You can connect transforms together with a digraph. And as long as that digraph makes sense, it'll all work correctly. Shell programming really ends up being limited. There are a few exceptions. You know, there's the T command. But other than that, you're really only doing things linearly. You can do some really nice, very complex things with transforms.

They're also a lot like audio units. If you've ever used audio units, used GarageBand, put things together, they also work on a sequence of changes. They're audio focused rather than being a general purpose system and their main focus is to be isochronous because it's audio. We're not isochronous, we're not real time, but we are concurrent.

And they're also kind of like Quartz Composer, where you have an image, you want to do a sequence of changes to the image to get something else. Again, transforms are a general purpose mechanism and they don't have a visual programming model like Quartz Composer, but it's like that. That gets you the idea of what we're doing with this. So it's data-driven. That's one of the really cool things. It's really easy to think about data-driven programming. It all revolves around core foundation. If we didn't have core foundation, we'd have to create something like it.

We need to have the sorts of arrays, dictionaries, descriptor-based data, so on and so forth. And by using core foundation, not only do we not have to do the work, but you get toll-free bridging to Cocoa. So anything that I talk about where I'll say, you know, CFData, CFError, you can translate that in your head into NS. And as a matter of fact, I sometimes pronounce CF NS myself. Lastly, this isn't a kernel interface. So, sorry. Now let me give you an example of how they work. So let's say you have a kernel.

The transform is an object. And like an object, it is its own self-contained thing. You talk to the transforms with what we call attributes. And attributes are just named slots. They're named with a string. They're like a dictionary. As a matter of fact, underneath, they are a dictionary.

You can have your attributes be whatever makes sense. So for crypto, key might be an obvious attribute that you would give this transform its key through an attribute named key. If you were doing RSS, you might have one called Article. If you were doing audio or video, you might do it with media.

Now in a generic sense and thinking of it kind of like the Unix pipelines, you have input and output and those are your equivalent of standard in and standard out. The data input comes in on the input one, it goes out through output and goes on from there to the next transform and on down the line.

To give you an example, we start with some data and we send the data through the input attribute to the first transform where it does its work, sends it on its output and its output is connected to the input of the next one and it does work and sends them on down the line. And all of these things can be running in parallel. And as a matter of fact, they will be running in parallel usually.

What goes on inside of them. One of the fun things that we've done with this is that you can take a transform set that you use, you set it up, you can save it, you can externalize it, and you can then bring it back in. So if you have gone to the trouble of doing some complex transform set to do your work, you can save it off, bring it in, and use it again.

Also, because we're using core foundation, it works equally well with C or Objective C. NS objects are easily castable through toll-free bridging to CF ones. And again, it's all blocks. Blocks, blocks, blocks. The attributes that we have get connected with connections to make the pipes. And they're like Unix pipes, they're I/O flows. And when you write to an attribute that's connected to somewhere else, it automatically flows from one to another. And this allows transforms to be able to focus their attention on exactly what they do and have everything work in a larger system together.

I've probably been thinking ahead and said, "Hmm, if you're going to have concurrent things doing lots of stuff in parallel, that means that you're going to have some issues with what happens when one of them outproduces what its consumer is, and so how do I keep from having maximal data explosion and so on?" Well, we've got flow control in two ways. There's implicit flow control and explicit flow control.

The implicit flow control is really just like I/O. Every attribute has an input queue, and if that input queue gets overflowed, too many things get written to it, the writer stalls. It's just like when you write to a file or you write to a pipe and nobody's read from it yet, you block until it finishes. So that's a really nice programming model because you don't have to change your head. It works just like a pipe. It works just like a file.

Explicit flow control is done through something that we call pushback. On any given attribute, you can push back one CF object on top of it. And that permits you to say, I'm not ready yet. So if I take my example where I'm doing cats and earthquakes, if I've got cats coming in because there are lots of cats and not as many earthquakes, I can push back the cats until I get an earthquake come in and then combine the two and go on.

Attributes are asynchronous, they can fire at any time, but there is a serialized queue inside of every transform that within a transform it acts like a process. This is an important thing to do because if we don't have that, if everything is truly asynchronous, then you have to worry about concurrency issues with yourself. Inside of a transform, it behaves like a process does. And that's what that serialization queue does, so that you don't have to worry about, "I'm reading from this attribute when another one comes in." It's not going to come in until you're done.

There are five special attributes that we have. I've already told you about input and output. They're the equivalent of standard in and standard out. All the transforms have to have names. That's necessary for when we let you save them and restore them. We name them with something random.

You can set to the label attribute if you want to name a transform yourself. There's no real reason to, but it's there. Jon Callas If you write to the abort attribute of any transform from inside or outside, that signals an error. That's pulling the emergency stop cord on the train. It all comes to a halt after that. The debug attribute is there for logging information.

The data that we deal with in transforms is most strictly all a CF type ref, which is a CF anything. You can write any CF thing to any attribute. You can type sniff it. You can do whatever you want for all sorts of really interesting calculations. Jon Callas Realistically, almost everything you're going to do is CFData.

Particularly for our implementation right now, we revolve around CFData because we did in fact start building this as being a data processing system and a crypto data processing system. Jon Callas CFData are the most first class of all things, but any CF object can be put onto things. Jon Callas Also, attributes can have multiple outgoing connections.

This is really useful not only for the times when you need to have output data going to two places, but it means that you can have debugging monitors connected to an attribute so that you could see what's coming out of anything if you are having to do your own debugging.

Jon Callas It also means that you could feed these things into progress bars or other UI elements where you want to have a tap on what's going on on the system itself. It's a really nice little feature that you can have that. So that's just one thing to remember as well. So I'm going to run through some code.

And I'm going to do a really simple one first. I mean, because if you think about something that you might do, you might say, read from a file, compress it, encrypt it, and then base 64 it. And you'd base it 60 for it because, like it or not, the internet in most cases wants its data to be 7-bit clean. And there are just all sorts of places that unrestricted binary data will give somebody a heart attack. So there are lots and lots of web programming cases where you need to take your binary data and base 60 for it.

So here's a code sample of how to do this with a transform. My first line is a CFData. It's my input. It's where I, you know, it's what I'm supposed to encode. I also have a CFError. We do all of our error reporting through CFErrors. And again, if you're used to NSErrors, CFErrors and NSErrors are close cousins.

We do them slightly differently than some people who do NSErrors because we have you set the error ref to null and we return back something if there is an error. If that error variable ever goes non-null, it means you have an error. So anyway, we're creating a transform here. And this is an encode transform. You can see that we have a constant for base64 encoding. There are other encodings as well. For example, there's zlib encoding.

And we get our coding transform. And in this line, you can see that there is a long constant for the string input in all caps. Much better to use the constant, but that's really all that it is. And we're writing the data onto the input attribute. To tell that transform, here's what we want you to operate on. And then we call sec transform execute. And that takes the transform, it would return an error in the CFErrorRef, and a CFData will come back to us that is a CFData of the resulting data. That's it. I mean, that's all you have to do now.

So let's go one more. Let's do two transforms. We're going to do encrypt and base64. First parameter that we have here is a SecKeyRef. That's a key coming from the security framework. This also is where this works a lot like a generic function. It also is something of a universal context. If you are used to CDSA, you know that CDSA has all sorts of things you've got to keep hold of. And we've reduced that tremendously. There's not that many things to keep hold of here.

Jon Callas That key can be an AES key. It could be an RSA key. It could be an elliptic curve key. It could have padding. It could have other things. I don't need to know and I don't care. I just know that it is a key that somebody set up for me.

Like before, we have the data that we're going to work on. And note here, we create a transform that is our encryption transform. An error would come back if there was a problem. Like before, I'm going to have the encoding transform. Now in this new little thing, we're creating a transform group. And a transform group is the handle. When you have a chain of them, you've got to have a handle.

Think of it as it's the six pack container that you put all the transforms in. It exists to have a place where we know what's going on, where all of the references to everything will be held, where we know where the graph of them is. And it's, you know, it's just the holder.

This line is where all the magic happens. To go through it quickly, I have the encryption transform and its output attribute and I have the encoding transform and its input attribute. And so I'm kind of drawing a line just like I did on the little graph from output to the input of the next one and I'm telling it what group I want them in and where to bring back any errors.

Like before, I take the start data, I put it onto the input of the first one, And in this particular case, I'm going to do an async call. The async call has the group and it also has this little abbreviated bit of code that I apologize for, but I wanted it to fit on only one screen. That's a block that's going to get called.

Jon Callas And that block is going to have three parameters, one of which is going to be a CFDataRef that holds the intermediate result. Well, sorry, the partial result. A CFError in case there was an error that happened in the middle. Jon Callas And a Boolean flag for whether or not this is the last one. And that block will get called every time there's a chunk go by.

It's entirely possible that you could get that called only once. It could be called one time for every byte. Now, you know, in this particular example, it's probably only going to get called once. But, you know, if you look at this, you can think how you would do it if you wanted to compress and then encrypt and then base 64 or read a file, compress. You just create a couple more transforms, connect them together, and particularly in the case of reading from a file, you would have little chunks going on.

The transform library that we've created for you for Lion has a bunch of basic cryptography in it. It's got encryption and decryption. It's got digital signatures, sign and verify. It's got hashes in HMACS, it's got key wrapping, and it's also got string to key, which will take like a password and produce a key out of that password. It's also got three flavors of encoding.

Base 32, Base 64, and Zlib. And you can use any of them, all of them. It's also got some miscellaneous things like file reading. So you can take a file or a stream and put it into a transform pipeline and have it work on that entire file or stream in the background for you and just let you know when something new comes in.

So next I want to talk about custom transforms, which is how to create ones of your own. We have sample code for you in the headers. If you go to seccustomtransform.h, there is a complete annotated example for the Caesar cipher. That's the root end cipher where, you know, it just adds end to every byte.

But the whole transform is there in the comments and you can take a look at it. You'll see all of the things that I'll be talking about in there and how we did them. And it's a nice example for knowing how to do a lot of basic transform. You know, we ourselves have essentially cut and paste from that as you go along.

When transforms run, they have a bunch of blocks that correspond to their own lifecycle events. And when the transform has an event occur, that block executes. When you make your own transform, you start with the null transform, which you can think of as being kind of like cat or like T since it's got multiple outputs, that would just pass data through. And you customize that one by adding your own blocks to whatever transform events you want to override. And so when that event occurs, your block will execute.

Now one of the really cool things about this is that these overrides are not just once. You can re-override at any time. So that means that you can start off with a reasonably generic implementation and you can say, aha, I know now that I could use my optimized implementation and just put the optimized block in place and everything keeps running. Jon Callas You can also do something rather complex like a state machine by doing your state transitions by having every state put the new state block into the right place.

The advantage of this is you can do a lot of really complex high level things where you can make this look like a easy to use, fun object oriented system and still have extraordinarily high performance because blocks really are just routines and it really is little more than a function call to get to them.

Now the main thing, there are two things that you do mostly. The first one is the attribute set notification event. And this is when somebody writes to an attribute, this block will fire. There are two ways that you can do it. You can either give a named attribute, like for example, key is a perfectly fine named attribute that you would want to catch that one in specific. Or you can have a catch all handler that hits anything.

If you have both, you know, if I have both key and the catchall and somebody sets my key attribute, only the key will execute, not the generic. But the generic one lets you do something so that if you want to know any time any attribute is done or a protocol that you would have that would have names that you wouldn't know in advance, you can handle that with the generic handler.

The other main one that everybody does is process data. And this is a shortcut for a handler on input The nice thing about processed data is that it pre-vets everything for you. You know that what has come in is a CFData. Also, when you return from the process data block, whatever you return gets passed on down the line. So you don't have to figure any of that out.

We do in the transform machinery that bookkeeping for you. So it means that you can write the process data routine as I get an input in, I return an output out. And that's all I have to do is that small little juggling act. A null gets sent to you as the equivalent of end of file. And if you return null, that's passing an end to file on down the line as well.

There are two other main lifecycle functions. Execute starting, which gets called right before everything goes. And this would be the place where you would allocate buffers if you need to open files or do anything. State that you need to do something. You start that up and execute starting.

And that's also one of the advantages of it that you don't have to test every time. You know that this is essentially we're starting now, so I need to prep. Jon Callas There's also finalize, which is the corresponding one that everything is done. You're about to be released, so you get rid of all of your extra things that you might have had.

That's pretty much all you have to do to write one. And I'm going to give an example now of code size comparison. On this I'm going to have on the left a program that we wrote using CDSA and on the right we're going to have the equivalent program that we wrote using transforms. This is a workload that we created that combined reading, coding, encryption, and so on.

And here's the source code of each one. You can see them going by. And you can also see that we met one of our main goals. 112 lines for the transforms whereas 1100 for CDSA, 112 for the transforms. That's a huge improvement in size, a huge improvement in just the simplicity of writing that.

We've got a speed comparison movie as well. In this, on the right, you'll see Activity Monitor. We ran this on a four core Mac Pro. So it's eight CPUs, four core Mac Pro, and when we start running that program, You'll see it go. Note that it runs kind of like what you would expect from a late 1990s architecture.

It's not really terribly efficiently using the CPUs. It's only using the A-side of every hyperthreaded pair. And that read a whole big file and did our workload on it. Now here is the transform version of that, the 112 line version of it. Now when I run this, don't blink. So there it goes. If you look at that.

That's GCD. I mean, GCD is what gives us all eight CPUs using, all eight CPUs being filled to capacity. I'm going to do that again because always when I do this, somebody blinks.

[Transcript missing]

10.1% of the code and over seven times performance improvement. Arthur Clarke said that any sufficiently advanced technology is indistinguishable from magic.

And my favorite magicians are Penn and Teller. So in that vein, I'm going to tell you how we did this. There are two things that we did to make this be a better demo. One of which was that we picked an 8 CPU system. If we'd done this on a two-core system, it would have run twice as fast. I mean, you know, it's rather obvious actually.

But we picked 8 CPUs. And if we'd picked 24 CPUs, it might have run up to 8 or a little more. But it wouldn't have run a whole lot faster than that because there wasn't enough work. And that's the other thing that we did was that we picked a workload that would fill an 8 CPU system.

The really impressive thing about this is that most times when you get a new programming system that is more high level, more easy to use, you end up with bottlenecks and slowdowns at execution time. One of the great things about transforms is that the more work you throw at it, the better you take your workload and break it up into small components, the better that GCD can figure out how to schedule it in parallel.

And that's a huge change from what we're used to before is that when you think about breaking your problem apart, it's better to break it up into small pieces rather than large pieces. Because every one of those small pieces can be running somewhere. Assuming, of course, you've got enough CPUs.

To summarize transforms, we started off with a way to speed up crypto. We needed to have a A better crypto system. And what we produced for crypto really is a general purpose concurrent programming system. You can use this for just about anything. We built it on the shoulders of the giants who went before us. The masterful work that went in Core Foundation and GCD is really what lets us be able to do this.

It also gives abstractions that let you reduce code size of the problems that you're solving and also mean that you can get order of magnitude improvements in the speed, assuming of course you have the right workload for it. But it's fast and it's small and what's not to like there? Last thing to talk about that I have is OpenSSL. This is probably not news to people because if you've been using any of the developer previews, you've probably seen this. We're deprecating the OpenSSL dialyps. And I want to repeat that again. We're deprecating the OpenSSL dialyps.

There are two major reasons why we're doing this. One of them is that OpenSSL does not have a stable application binary interface. They didn't design it to be used in dial-ins. The data structures change in between extremely minor releases. As an example, when we upgraded OpenSSL from 0.98q to 0.98r, there were a number of people who had their programs break because OpenSSL had changed some internal data structures and things flipped around.

It just isn't designed for that. Also, we need a FIPS 140 platform that is stable and under our control. You need to have dialybs to be able to do A FIPS 140 validation, you can't just do it on static libraries. And we need to have something that we're using ourselves for that.

So maybe you'll want to migrate. You know, maybe you won't. If you are using our stuff, if you're primarily a Mac OS or iOS programmer, Migrating might be a good thing to do. There's a lot of advantages that we've got.

[Transcript missing]

A special instruction said, "Oh, what version of vector registers do I happen to have? We'll do that for you and we'll give you the right one." We give you the small code size, we give you the concurrency, we give you the easy programming. There's also, you want to inherit our evaluations.

If you're calling into our code, it's essentially validated because you're calling our validated module as they call it. This is what we're doing ourselves. We're migrating everything in Mac OS and iOS away from OpenSSL towards our architecture. And if you want to do this and we have not given you yet what you need, tell us. Bugreporter.apple.com, tell us. This is how we know, this is how we prioritize.

If you're going to do this, the most closely related thing to OpenSSL crypto programming we have is common crypto. It's low-level C things. If you're going to go a little high level, then security framework and transforms are where you might go, but usually people who are using OpenSSL are using a common crypto-like API anyway. Jon Callas Now, if you're using SSL/TLS as a secure transport, our secure transport library is My opinion, the best SSL library that's out there, it's held up to abuse better than any of the others.

If you're using CF networking, if you're using NSURL anything, you're already doing it. So if you are already using NSURL and opening up an HTTPS, "You're using secure transport. You didn't have to do anything. And similarly, if you go to CF network and do SSL over that, you're using our secure transport.

You don't have to do anything. You already have." There's a lot of people though that this is not a good answer and we know that. If you're writing a Unix application, if you are doing something that is going to be running not on just our OSs but Linux, OpenBSD, you name it.

Our APIs are not an option for you. You might also already be using OpenSSL. It might be the devil you know. You know, yeah, okay, fine, it's got a lot of problems, but, you know, I've been dealing with them for the last 10 years anyway. Then, you know, stay where you are.

What you should do is go to macports.org. That's where the most recent version always is. 1.0.0d is already there. I checked it. Statically link the libraries. That's what they want you to do anyway. They say that when they do an update, you should be recompiling from source anyway. If you need the command line tools or other bits of OpenSSL that aren't the libraries themselves, include them in your bundle. It's the correct thing to do. It's what they recommend, it's what we recommend now as well because we don't like dialy version skew anymore than you do.

So let me wrap up. We are deprecating CDSA. We are deprecating the dialybs of OpenSSL. We know that we do not have complete replacements. Please help us do what you need. Bugreporter.apple.com. I'll say that one last time. Common Crypto is our low-level interface. It's for bare-to-the-metal C programmers. Transforms are our core foundation API.

They started off as being a way to get fast crypto. They build on GCD and core foundation to give you order of magnitude improvements in code size and speed. For related sessions, well there was a really good security overview on Tuesday. If you're watching this on video, if you haven't seen that yet, go watch it. It's a good session. And thank you very much.