Skip navigation.

Log in | Sign up

Opera Core Concerns

Official blog for Core developers at Opera

February 2009

( Monthly archive )

New in Opera Presto 2.2: TLS 1.2 Support

, , , ...

One of the new, but less obvious, features in Opera Presto 2.2 and Opera 10 is support for version 1.2 of the Transport Layer Security (TLS) protocol, the protocol formerly known as SSL.

TLS 1.2 was released as RFC 5246 last August, replacing TLS 1.1 (RFC 4346).

What is new in TLS 1.2?

This version of the protocol has several new features:

  • The way calculation of encryption keys is performed is made more dynamic, and new ciphersuites (set of encryption methods used by a connection) can define their own method, rather than having only the default one. This was necessary because some suites, such as a russian one, could not be used with the default method.
  • The default digest method is now SHA-256, offering stronger security.
  • Several new cipher suites (using existing encryption methods) also use SHA-256.
  • It has better ways to negotiate what signature algorithms the client supports.


Using SHA-256 as the digest method means we are using a more secure method for all the important calculations, and it removes TLS's dependency on MD5. While MD5 is used in a fashion that should reduce the impact of, if not eliminate, the problems the MD5 method is now encountering, the fact that the method is crumbling is, at best, problematic for TLS 1.1 and TLS 1.0.

Additionally, the document now includes the TLS extensions specification. This means that developers no longer need two documents to get all details about the formats used for these.

The document also added an implementor's checklist, making it easier for developers to catch mistakes early. This was added in part due to Opera's findings about the lack of interoperability between many clients and servers, often due to server-side implementation errors.

There are currently few, if any, production servers using TLS 1.2, which is to be expected for a new protocol version, but there are a couple of test servers available.

What is new in Opera relating to TLS?

Adapting Opera's TLS stack to support TLS 1.2 required some significant changes, mostly caused by the new flexibility in the key calculation.

The TLS feature testing, which determines the highest version of TLS supported by the server, was also slightly modified, and it will now always require TLS Extensions for TLS 1.1 and higher. We will also, in future upgrades, assume that any server supporting TLS 1.1 or higher will not panic if the client offers a protocol version newer than it supports, and will, in the future, test TLS 1.0, TLS 1.0+extenstion, TLS 1.1
(w/extenstion) and then the highest TLS version we support. A few years down the road we may also remove this cumbersome method, and offer our highest version in the first connection.

These changes resulted in a redesign with so many deep changes that the dormant support for SSL v2 was removed completely from the source code. Although the binary formats of TLS 1.2 and SSL v2 are incompatible, it is possible for them to co-exist, but the cost of making sure the inactive code actually worked would be too high. SSL v2 has been disabled by default in Opera since v8.0, and the actual functionality was disabled completely in 9.5. It would just not be economical to make sure this protocol version still works, along with the associated internal structure changes, when we have no intention of reactivating the code again. Instead, it was much easier to just "tear out" the code.

Testing

If you want to test TLS 1.2, Michael D'Errico, who's developing his own TLS toolkit, has graciously agreed to let you test against his server at https://www.mikestoolbox.net/. This server is using two private Root Certificates, <1> and <2> which you may want to import into your test configuration (it may be necessary to reload after a negotiation error once if you don't install it). When importing the certificates, after saving them to disk, you must remember to click "View" to go to the details dialog, and uncheck the "Warn about" checkbox, before completing the installation. When connecting to Michael's server you should get a page that includes these two lines:


TLS version: 1.2
Cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (006B)



Mike was quite helpful while we were debugging our implementation and helped clear up several mistakes. We also use his server in our automatic regression tests, and we thank him for the assistance.

First Root Certificate for Mikes Toolbox
Second Root Certificate for Mikes Toolbox (needed in 10.0)

Carakan

, ,

Over the past few months, a small team of developers and testers have been working on implementing a new ECMAScript/JavaScript engine for Opera. When Opera's current ECMAScript engine, called Futhark, was first released in a public version, it was the fastest engine on the market. That engine was developed to minimize code footprint and memory usage, rather than to achieve maximum execution speed. This has traditionally been a correct trade-off on many of the platforms Opera runs on. The Web is a changing environment however, and tomorrow's advanced web applications will require faster ECMAScript execution, so we have now taken on the challenge to once again develop the fastest ECMAScript engine on the market.

The name Carakan, like the names of Opera's previous ECMAScript engines, Futhark, Linear A and Linear B, is the name of a writing system, or "script".

We have focused our efforts to improve upon our previous engine in three main areas:

Register-based bytecode

The last couple of generations of Opera's ECMAScript engine have used a stack-based bytecode instruction set. This type of instruction set is based around a stack of values, where most instructions "pop" input operands from the value stack, process them, and "push" the result back onto the value stack. Some instructions simply push values onto the value stack, and others rearrange the values on the stack. This gives compact bytecode programs and is easy to generate bytecode for.

In the new engine, we've instead opted for a register-based bytecode instruction set. In a register-based machine, instead of a dynamically sized stack of values, there's a fixed size block of them, called "registers". Instead of only looking at the values at the top of the stack, each instruction can access any register. Since there is no need to copy values to and from the top of the stack to work on them, fewer instructions need to be executed, and less data needs to be copied.

Native code generation

Although our new engine's bytecode instruction set permits the implementation of a significantly faster bytecode execution engine, there is still significant overhead involved in executing simple ECMAScript code, such as loops performing integer arithmetics, in a bytecode interpreter. To get rid of this overhead we are implementing compilation of whole or parts of ECMAScript programs and functions into native code.

This native code compilation is based on static type analysis (with an internal type system that is richer than ECMAScript's ordinary one) to eliminte unnecessary type-checks, speculative specialization (with regards to statically indeterminate types) where appropriate, and a relatively ambitious register allocator that allows generation of compact native code with as few unnecessary inter-register moves and memory accesses as possible.

On ECMAScript code that is particularly well-suited for native code conversion, our generated native code looks more or less like assembly code someone could have written by hand, trying to keep everything in registers.

The register allocator is designed to be architecture independent, and so is the code generation "frontend" where most of the complicated decisions are made. We have initially implemented a backend for 32- and 64-bit x86, but some preliminary work has already started to generate native code for other CPU architectures, such as ARM.

In addition to generating native code from regular ECMAScript code, we also generate native code that performs the matching of simple regular expressions. This improves performance a lot when searching for matches of simple regular expressions in long strings. For sufficiently long strings, this actually makes searching for a substring using a regular expression faster than the same search using String.prototype.indexOf. For shorter strings, the speed is limited by the overhead of compiling the regular expression.

For more complex regular expressions, native code generation becomes more involved, and improves performance less since the regular expression engine is already reasonably fast. The base regular expression engine is a newly developed one, but it's already made its debut in Presto 2.2 (the browser engine used in Opera 10 Alpha). It's fundamentally a typical backtracking regular expression engine, but does some tricks to avoid redundant backtracking, which usually avoids the severe performance issues a backtracking regular expression engine can have on specific regular expressions.

Automatic object classification

Another area of major improvement over our current engine is in the representation of ECMAScript objects. In the new engine, each object is assigned a class that collects various information about the object, such as its prototype and the order and names of some or all of its properties. Class assignment is naturally very dynamic, since ECMAScript is a very dynamic language, but it is organized such that objects with the same prototype and the same set of properties are assigned the same class.

This representation allows compact storage of individual objects, since most of the complicated structures representing the object's properties are stored in the class, where they are shared with all other objects with the same class. In real-world programs with many objects of the same classes, this can save significant amounts of memory. It can be expected that most programs that do create many objects still only have a few different classes of objects.

The shared lookup structures for properties also allow us to share the result of looking up a property between different objects. For two objects with the same class, if the lookup of a property "X" on the first object gave the result Y, we know that the same lookup on the second object will also give the result Y. We use this to cache the result of individual property lookups in ECMAScript programs, which greatly speeds up code that contains many property reads or writes.

Performance

So how fast is Carakan? Using a regular cross-platform switch dispatch mechanism (without any generated native code) Carakan is currently about two and a half times faster at the SunSpider benchmark than the ECMAScript engine in Presto 2.2 (Opera 10 Alpha). Since Opera is ported to many different hardware architectures, this cross-platform improvement is on its own very important.

The native code generation in Carakan is not yet ready for full-scale testing, but the few individual benchmark tests that it is already compatible with runs between 5 and 50 times faster, so it is looking promising so far.

Vega - Opera's vector graphics library

, , , ...

In my previous post here at Core concerns I wrote a bit about hardware acceleration of Opera's vector graphics library. In this post I will go into some more details about our vector graphics library.

The history of Vega

Vega was created shortly after we started working on SVG support. When we added SVG support in Opera we needed a vector graphics library. We looked into what was available to use and met our requirements (fast, low memory usage and works on platforms ranging from phones to TVs and desktop computers). We did not find and good match for our needs, so we decided to write our own.

Shortly after we created Vega we added <canvas> support, which also uses Vega.

The most recent addition to Vega is the ability to use a hardware accelerated back-end. The back-ends we are using at the moment are OpenGL and Direct3D.

HTML rendering

In the core version we are currently developing, Presto 2.3, we have made it possible to use Vega for all rendering in Opera. This means that we can replace the platform specific code for rendering with Vega. In the future it might be mandatory to use Vega for rendering, but in Presto 2.3 it is still possible to use the old rendering back-ends.

There are three reasons for doing this. The first reason is that the new CSS3 background and borders standard is much easier to implement using a vector graphics library. Presto 2.3 adds partial support for CSS3 backgrounds and borders, but only when using Vega for rendering.

The second reason is to support hardware acceleration of our vector graphics. In order to be able to render SVG and <canvas> in hardware we must also be able to directly draw the rendered vector graphics to the screen since reading back the rendered image from the graphics card is usually slower than rendering in software.

The final reason is that it enables us to easily add advanced graphical effects to our UI and to web pages.

Hardware requirements

The hardware back-end of Vega will unfortunately not work on all graphics cards. The good news is that we detect at runtime if your graphics card is supported or not and fallback to the software back-end of Vega if the graphics card is not supported. This means that everything will work regardless of your graphics cards capabilities.

The first requirement of you graphics card is that it has fast stencil buffers. If you are on a desktop computer that will not be a problem, but on some mobile phones that will be a problem. The reason for this requirement is that we use the stencil buffer for rendering some complex shapes instead of tessellating them and render triangles.

Since some web standards (for example opacity, SVG and <canvas>) require us to render to an off-screen buffer which is composited onto the screen we also require some kind of render to texture to be able to use Vega hardware back-end. This means a DirectX 9 compatible graphics card, or support for the framebuffer object (FBO) extension in OpenGL. It would be possible to do the same thing with pbuffers in OpenGL, but we need to do many render target switches and with pbuffers that is too slow.

The final requirement is pixel shaders 2.0, or fragment shaders 2.0 as it is called in OpenGL. We also require GLSL support on OpenGL. The shaders are required for filters. Filters is a part of SVG which performs an operation such as blur or color transforms on an image. Filters are also used in <canvas> and to support text shadows and box shadows in HTML.

For a PC user these requirements are met by any DirectX 9 compatible graphics card. So with the correct drivers you should be able to use the hardware back-end of Vega if you have a DirectX 9 compatible graphics card.

Update 2009-02-05:

I was not very clear about the multiple back-ends of Vega. If the graphics card is not capable of running the hardware back-end of Vega the software back-end will be used as a fallback and all features will still work. No features depends on hardware acceleration. All of them, including CSS3 backgrounds and borders, will work in the software back-end of Vega which does not depend on hardware accelerated graphics.