text:
AES-GCM-SIV (14 May 2017)
AEADs combine encryption and authentication in a way that provides the properties that people generally expect when they "encrypt" something. This is great because, historically, handing people a block cipher and a hash function has resulted in a lot of bad and broken constructions. Standardising AEADs avoids this.
Common AEADs have a sharp edge though: you must never encrypt two different messages with the same key and nonce. Doing so generally violates the confidentiality of the two messages and might break much more.
There are some situations where obtaining a unique nonce is easy, for example in transport security where a simple counter can be used. (Due to poor design in TLS 1.2, some TLS implementations still managed to duplicate nonces. The answer there is to do what ChaCha20-Poly1305 does in TLS 1.2, and what everything does in TLS 1.3: make the nonce implicit. That means that any mistakes result in your code not interoperating, which should be noticed.)
But there are situations where ensuring nonce uniqueness is not trivial, generally where multiple machines are independently encrypting with the same key. A system for distributing nonces is complex and hard to have confidence in. Generating nonces randomly and depending on statistical uniqueness is reasonable, but only if the space of nonces is large enough. XSalsa20-Poly1305 (paper, code) has a 192-bit nonce and good performance across a range of CPUs. In many situations, using that with random nonces is a sound choice.
However, lots of chips now have hardware support for the AES-GCM AEAD, meaning that its performance and power use is hard to beat. Also, a 192-bit nonce results in a ~40% increase in overhead vs the 96-bit nonce of AES-GCM, which is undesirable in some contexts. (Overhead consists of the nonce and tag, thus the increase from 96- to 192-bit nonces is not 100%.)
But using random nonces in a 96-bit space isn't that comfortable. NIST recommends a limit of 232 messages when using random nonces with AES-GCM which, while quite large, is often not large enough not to have to worry about. Because of this, Shay Gueron, Yehuda Lindell and I have been working on AES-GCM-SIV (paper, spec): AES-GCM with some forgiveness. It uses the same primitives as AES-GCM, and thus enjoys the same hardware support, but it doesn't fail catastrophically if you repeat a nonce. Thus you can use random, 96-bit nonces with a far larger number of messages, or withstand a glitch in your nonce distribution scheme. (For precise numbers, see section 5.3 of the paper.)
There is a performance cost: AES-GCM-SIV encryption runs at about 70% the speed of AES-GCM, although decryption runs at the same speed. (Measured using current BoringSSL on an Intel Skylake chip with 8KiB messages.) But, in any situation where you don't have a watertight argument for nonce uniqueness, that might be pretty cheap compared to the alternative.
For example, both TLS and QUIC need to encrypt small messages at the server that can be decrypted by other servers. For TLS, these messages are the session tickets and, in QUIC, they are the source-address tokens. This is an example of a situation where many servers are independently encrypting with the same key and so Google's QUIC implementation is in the process of switching to using AES-GCM-SIV for source-address tokens. (Our TLS implementation may switch too in the future, although that will be more difficult because of existing APIs.)
AEADs that can withstand nonce duplication are called "nonce-misuse resistant" and that name appears to have caused some people to believe that they are infinitely resistant. I.e. that an unlimited number of messages can be encrypted with a fixed nonce with no loss in security. That is not the case, and the term wasn't defined that way originally by Rogaway and Shrimpton (nor does their SIV mode have that property). So it's important to emphasise that AES-GCM-SIV (and nonce-misuse resistant modes in general) are not a magic invulnerability shield. Figure four and section five of the the paper give precise bounds but, if in doubt, consider AES-GCM-SIV to be a safety net for accidental nonce duplication and otherwise treat it like a traditional AEAD.
AES-GCM-SIV is supported in BoringSSL now and, while one may not want to use the whole of BoringSSL, the core assembly is ISC licensed. Also, Shay has published reference, assembly and intrinsics versions for those who think AES-GCM-SIV might be useful to them.
CFI directives in assembly files (18 Jan 2017)
(This post uses x86-64 for illustration throughout. The fundamentals are similar for other platforms but will need some translation that I don't cover here.)
Despite compilers getting better over time, it's still the case that hand-written assembly can be worthwhile for certain hot-spots. Sometimes there are special CPU instructions for the thing that you're trying to do, sometimes you need detailed control of the resulting code and, to some extent, it remains possible for some people to out-optimise a compiler.
But hand-written assembly doesn't automatically get some of the things that the compiler generates for normal code, such as debugging information. Perhaps your assembly code never crashes (although any function that takes a pointer can suffer from bugs in other code) but you probably still care about accurate profiling information. In order for debuggers to walk up the stack in a core file, or for profilers to correctly account for CPU time, they need be able to unwind call frames.
Unwinding used to be easy as every function would have a standard prologue:
push rbp mov rbp, rsp
This would make the stack look like this (remember that stacks grow downwards in memory):
So, upon entry to a function, the CALL instruction that jumped to the function in question will have pushed the previous program counter (from the RIP register) onto the stack. Then the function prologue saves the current value of RBP on the stack and copies the current value of the stack pointer into RBP. From this point until the function is complete, RBP won't be touched.
This makes stack unwinding easy because RBP always points to the call frame for the current function. That gets you the saved address of the parent call and the saved value of its RBP and so on.
The problems with this scheme are that a) the function prologue can be excessive for small functions and b) we would like to be able to use RBP as a general purpose register to avoid spills. Which is why the GCC documentation says that "-O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging". This means that you can't depend on being able to unwind stacks like this. A process can be comprised of various shared libraries, any of which might be compiled with optimisations.
To be able to unwind the stack without depending on this convention, additional debugging tables are needed. The compiler will generate these automatically (when asked) for code that it generates, but it's something that we need to worry about when writing assembly functions ourselves if we want profilers and debuggers to work.
The reference for the assembly directives that we'll need is here, but they are very lightly documented. You can understand more by reading the DWARF spec, which documents the data that is being generated. Specifically see sections 6.4 and D.6. But I'll try to tie the two together in this post.
The tables that we need the assembler to emit for us are called Call Frame Information (CFI). (Not to be confused with Control Flow Integrity, which is very different.) Based on that name, all the assembler directives begin with .cfi_.
Next we need to define the Canonical Frame Address (CFA). This is the value of the stack pointer just before the CALL instruction in the parent function. In the diagram above, it's the value indicated by "RSP value before CALL". Our first task will be to define data that allows the CFA to be calculated for any given instruction.
The CFI tables allow the CFA to be expressed as a register value plus an offset. For example, immediately upon function entry the CFA is RSP + 8. (The eight byte offset is because the CALL instruction will have pushed the previous RIP on the stack.)
As the function executes, however, the expression will probably change. If nothing else, after pushing a value onto the stack we would need to increase the offset.
So one design for the CFI table would be to store a (register, offset) pair for every instruction. Conceptually that's what we do but, to save space, only changes from instruction to instruction are stored.
It's time for an example, so here's a trivial assembly function that includes CFI directives and a running commentary.
.globl square .type square,@function .hidden square square:
This is a standard preamble for a function that's unrelated to CFI. Your assembly code should already be full of this.
Our first CFI directive. This is needed at the start of every annotated function. It causes a new CFI table for this function to be initialised.
.cfi_def_cfa rsp, 8
This is defining the CFA expression as a register plus offset. One of the things that you'll see compilers do is express the registers as numbers rather than names. But, at least with GAS, you can write names. (I've included a table of DWARF register numbers and names below in case you need it.)
Getting back to the directive, this is just specifying what I discussed above: on entry to a function, the CFA is at RSP + 8.
push rbp .cfi_def_cfa rsp, 16
After pushing something to the stack, the value of RSP will have changed so we need to update the CFA expression. It's now RSP + 16, to account for the eight bytes we pushed.
mov rbp, rsp .cfi_def_cfa rbp, 16
This function happens to have a standard prologue, so we'll save the frame pointer in RBP, following the old convention. Thus, for the rest of the function we can define the CFA as RBP + 16 and manipulate the stack without having to worry about it again.
mov DWORD PTR [rbp-4], edi mov eax, DWORD PTR [rbp-4] imul eax, DWORD PTR [rbp-4] pop rbp .cfi_def_cfa rsp, 8
We're getting ready to return from this function and, after restoring RBP from the stack, the old CFA expression is invalid because the value of RBP has changed. So we define it as RSP + 8 again.
ret .cfi_endproc
At the end of the function we need to trigger the CFI table to be emitted. (It's an error if a CFI table is left open at the end of the file.)
The CFI tables for an object file can be dumped with objdump -W and, if you do that for the example above, you'll see two tables: something called a CIE and something called an FDE.
The CIE (Common Information Entry) table contains information common to all functions and it's worth taking a look at it:
… CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8
You can ignore everything until the DW_CFA_… lines at the end. They define CFI directives that are common to all functions (that reference this CIE). The first is saying that the CFA is at RSP + 8, which is what we had already defined at function entry. This means that you don't need a CFI directive at the beginning of the function. Basically RSP + 8 is already the default.
The second directive is something that we'll get to when we discuss saving registers.
If we look at the FDE (Frame Description Entry) for the example function that we defined, we see that it reflects the CFI directives from the assembly:
… FDE cie=… DW_CFA_advance_loc: 1 to 0000000000000001 DW_CFA_def_cfa: r7 (rsp) ofs 16 DW_CFA_advance_loc: 3 to 0000000000000004 DW_CFA_def_cfa: r6 (rbp) ofs 16 DW_CFA_advance_loc: 11 to 000000000000000f DW_CFA_def_cfa: r7 (rsp) ofs 8
The FDE describes the range of instructions that it's valid for and is a series of operations to either update the CFA expression, or to skip over the next n bytes of instructions. Fairly obvious.
Optimisations for CFA directives
There are some shortcuts when writing CFA directives:
Firstly, you can update just the offset, or just the register, with cfi_def_cfa_offset and cfi_def_cfa_register respectively. This not only saves typing in the source file, it saves bytes in the table too.
Secondly, you can update the offset with a relative value using cfi_adjust_cfa_offset. This is useful when pushing lots of values to the stack as the offset will increase by eight each time.
Here's the example from above, but using these directives and omitting the first directive that we don't need because of the CIE:
.globl square .type square,@function .hidden square square: .cfi_startproc push rbp .cfi_adjust_cfa_offset 8 mov rbp, rsp .cfi_def_cfa_register rbp mov DWORD PTR [rbp-4], edi mov eax, DWORD PTR [rbp-4] imul eax, DWORD PTR [rbp-4] pop rbp .cfi_def_cfa rsp, 8 ret .cfi_endproc
Saving registers
Consider a profiler that is unwinding the stack after a profiling signal. It calculates the CFA of the active function and, from that, finds the parent function. Now it needs to calculate the parent function's CFA and, from the CFI tables, discovers that it's related to RBX. Since RBX is a callee-saved register, that's reasonable, but the active function might have stomped RBX. So, in order for the unwinding to proceed it needs a way to find where the active function saved the old value of RBX. So there are more CFI directives that let you document where registers have been saved.
Registers can either be saved at an offset from the CFA (i.e. on the stack), or in another register. Most of the time they'll be saved on the stack though because, if you had a caller-saved register to spare, you would be using it first.
To indicate that a register is saved on the stack, use cfi_offset. In the same example as above (see the stack diagram at the top) the caller's RBP is saved at CFA - 16 bytes. So, with saved registers annotated too, it would start like this:
square: .cfi_startproc push rbp .cfi_adjust_cfa_offset 8 .cfi_offset rbp, -16
If you need to save a register in another register for some reason, see the documentation for cfi_register.
If you get all of that correct then your debugger should be able to unwind crashes correctly, and your profiler should be able to avoid recording lots of detached functions. However, I'm afraid that I don't know of a better way to test this than to zero RBP, add a crash in the assembly code, and check whether GBD can go up correctly.
(None of this works for Windows. But Per Vognsen, via Twitter, notes that there are similar directives in MASM.)
CFI expressions
New in version three of the DWARF standard are CFI Expressions. These define a stack machine for calculating the CFA value and can be useful when your stack frame is non-standard (which is fairly common in assembly code). However, there's no assembler support for them that I've been able to find, so one has to use cfi_escape and provide the raw DWARF data in a .s file. As an example, see this kernel patch.
Since there's no assembler support, you'll need to read section 2.5 of the standard, then search for DW_CFA_def_cfa_expression and, perhaps, search for cfi_directive in OpenSSL's perlasm script for x86-64 and the places in OpenSSL where that is used. Good luck.
(I suggest testing by adding some instructions that write to NULL in the assembly code and checking that gdb can correctly step up the stack and that info reg shows the correct values for callee-saved registers in the parent frame.)
CFI register numbers
In case you need to use or read the raw register numbers, here they are for a few architectures:
|Register number
|ESP(may be EBP on MacOS)
|EBP(may be ESP on MacOS)
(x86 values taken from page 25 of this doc. x86-64 values from page 57 of this doc. ARM taken from page 7 of this doc.)
RISC-V assembly (31 Dec 2016)
RISC-V is a new, open instruction set. Fabrice Bellard wrote a Javascript emulator for it that boots Linux here (more info). I happen to have just gotten a physical chip that implements it too (one of these) and what's cool is that you can get the source code to the chip on GitHub.
The full, user-level instruction set is documented but there's a lot of information in there. I wanted a brief summary of things that I could keep in mind when reading disassembly. This blog post is just a dump of my notes; it's probably not very useful for most people! It also leaves out a lot of things that come up less frequently. There's also an unofficial reference card which is good, but still aimed a little low for me.
RISC-V is little-endian and comes in 32 and 64 bit flavours. In keeping with the RISC-V documents, the flavour (either 32 or 64) is called XLEN below in the few places where it matters.
For both, int is 32 bits. Pointers and long are the native register size. Signed values are always sign extended in a larger register and unsigned 8- and 16-bit values are zero extended. But unsigned 32-bit values are sign-extended. Everything has natural alignment in structs and the like, but alignment isn't required by the hardware.
The stack grows downwards and is 16-byte aligned upon entry to a function.
Instructions are all 32 bits and 32-bit aligned. There is a compressed-instruction extension that adds 16-bit instructions and changes the required alignment of all instructions to just 16 bits. Unlike Thumb on ARM, RISC-V compressed instructions are just a short-hand for some 32-bit instruction and 16- and 32-bit instructions can be mixed freely.
There are 31 general purpose registers called x1–x31. Register x0 drops all writes and always reads as zero. Each register is given an alias too, which describes their conventional use:
|Saved by
|Return address
|Stack pointer
|Global pointer
|Thread pointer
|Saved register / frame pointer
|Saved register
|Arguments and return values
|Saved registers
There are two types of immediates, which will be written as 'I' and 'J'. Type 'I' intermediates are 12-bit, signed values and type 'J' are 20-bit, signed values. They are always sign-extended to the width of a register before use.
There's no carry flag, instead one has to use a comparison instruction on the result in order to get the carry in a register.
A U suffix indicates an unsigned operation. Note that the multiplication and division instructions are part of the 'M' extension, but I expect most chips to have them.
|ADD dest,src1,src2
|dest = src1 + src2
|SUB dest,src1,src2
|dest = src1 - src2
|ADDI dest,src1,I
|dest = src1 + I
|MUL dest,src1,src2
|dest = src1 × src2
|MULH[|U|SH] dest,src1,src2
|dest = (src1 × src2) >> XLEN
|This returns the high word of the multiplication result for signed×signed, unsigned×unsigned or signed×unsigned, respectively
|DIV[U] dest,src1,src2
|dest = src1/src2
|There's no trap on divide-by-zero, rather special values are returned. (See documentation.)
|REM[U] dest,src1,src2
|dest = src1%src2
These should all be obvious:
|AND dest,src1,src2
|OR dest,src1,src2
|XOR dest,src1,src2
|ANDI dest,src1,I
|ORI dest,src1,I
|XORI dest,src1,I
Instructions here are Shift [Left|Right] [Logical|Arithmetic].
Note that only the minimal number of bits are read from the shift count. So shifting by the width of the register doesn't zero it, it does nothing.
|SLL dest,src1,src2
|dest = src1 << src2%XLEN
|SRL dest,src1,src2
|dest = src1 >> src2%XLEN
|SRA dest,src1,src2
|dest = src1 >> src2%XLEN
|SLLI dest,src1,0‥31/63
|dest = src1 << I
|SRLI dest,src1,0‥31/63
|dest = src1 >> I
|SRAI dest,src1,0‥31/63
|dest = src1 >> I
These instructions set the destination register to one or zero depending on whether the relation is true or not.
|SLT dest,src1,src2
|dest = src1<src2
|(signed compare)
|SLTU dest,src1,src2
|dest = src1<src2
|(unsigned compare)
|SLTI dest,src1,I
|dest = src1<I
|(signed compare)
|SLTIU dest,src1,I
|dest = src1<I
|(unsigned compare, but remember that the immediate is sign-extended first)
Control flow
The JAL[R] instructions write the address of the next instruction to the destination register for the subsequent return. This can be x0 if you don't care.
Many instructions here take an immediate that is doubled before use. That's because no instruction (even with compressed instructions) can ever start on an odd address. However, when you write the value in assembly you write the actual value; the assembler will halve it when encoding.
|JAL dest,J
|dest = pc+2/4; pc+=2*J
|JALR dest,src,I
|dest = pc+2/4; pc=src1+(I&~1)
|Note that the least-significant bit of the address is ignored
|BEQ src1,src2,I
|if src1==src2, pc+=2*I
|BNE src1,src2,I
|if src1!=src2, pc+=2*I
|BLT src1,src2,I
|if src1<src2, pc+=2*I
|signed compare
|BLTU src1,src2,I
|if src1<src2, pc+=2*I
|unsigned compare
|BGE src1,src2,I
|if src1>=src2, pc+=2*I
|signed compare
|BGEU src1,src2,I
|if src1>=src2, pc+=2*I
|unsigned compare
The suffix on these instructions denotes the size of the value read or written: 'D' = double-word (64 bits), 'W' = word (32 bits), 'H' = half-word (16 bits), ´B' = byte. Reading and writing 64-bit values only works on 64-bit systems, and LWU only exists on 64-bit systems because it's the same as LW otherwise.
Alignment is not required, but might be faster. Also note that there's no consistent direction of data flow in the textual form of the assembly: the register always comes first.
|L[D|W|H|B] dest,I(src)
|dest = *(src + I)
|result is sign extended
|L[D|W|H|B]U dest,I(src)
|dest = *(src + I)
|result is zero extended
|S[D|W|H|B] src1,I(src2)
|*(src2 + I) = src1
|LUI dest,J
|dest = J<<12
|"Load Upper Immediate". The result is sign extended on 64-bit.
|AUIPC dest,J
|dest = pc + J<<12
|"Add Upper Immediate to PC". The result of the shift is sign-extended on 64-bit before the addition.
W instructions
These instructions only exist on 64-bit and are copies of the same instruction without the 'W' suffix, except that they operate only on the lower 32 bits of the registers and, when writing the result, sign-extend to 64 bits. They are ADDW, SUBW, ADDIW, DIV[U]W, REM[U]W, S[L|R]LW, SRAW, S[L|R]LIW and SRAIW
For clarity, there are also a number of pseudo-instructions defined. These are just syntactic sugar for one of the primitive instructions, above. Here's a handful of the more useful ones:
|addi x0,x0,0
|mv dest,src
|addi dest,src,0
|not dest,src
|xor dest,src,-1
|seqz dest,src
|sltiu dest,src,1
|snez dest,src
|sltu dest,x0,src
|j J
|jal x0,J
|jalr x0,x1,0
|call offset
|auipc x6, offset >> 12; jalr x1,x6,offset & 0xfff
|li dest,value
|(possibly several instructions to load arbitrary value)
|la dest,symbol
|auipc dest, symbol >> 12; addi dest,dest,offset & 0xfff
|l[d|w|h|b] dest,symbol
|auipc dest, symbol >> 12; lx dest,offset & 0xfff(dest)
|s[d|w|h|b] src,symbol
|auipc dest, symbol >> 12; sx dest,offset & 0xfff(dest)
Note that the instructions that expand to two instructions where the first is AUIPC aren't quite as simple as they appear. Since the 12-bit immediate in the second instruction is sign extended, it could end up negative. If that happens, the J immediate for AUIPC needs to be one greater and then you can reach the value by subtracting from there.
CECPQ1 results (28 Nov 2016)
In July my colleague, Matt Braithwaite, announced that Chrome and Google would be experimenting with a post-quantum key-agreement primitive in TLS. One should read the original announcement for details, but we had two goals for this experiment:
Firstly we wanted to direct cryptoanalytic attention at the family of Ring Learning-with-Errors (RLWE) problems. The algorithm that we used, NewHope, is part of this family and appeared to be the most promising when we selected one at the end of 2015.
It's very difficult to know whether we had any impact here, but it's good to see the recent publication and withdrawal of a paper describing a quantum attack on a fundamental lattice problem. Although the algorithm contained an error, it still shows that capable people are testing these new foundations.
Our second goal was to measure the feasibility of deploying post-quantum key-agreement in TLS by combining NewHope with an existing key-agreement (X25519). We called the combination CECPQ1.
TLS key agreements have never been so large and we expected a latency impact from the extra network traffic. Also, any incompatibilities with middleboxes can take years to sort out, so it's best to discover them as early as possible.
Here the results are more concrete: we did not find any unexpected impediment to deploying something like NewHope. There were no reported problems caused by enabling it.
Although the median connection latency only increased by a millisecond, the latency for the slowest 5% increased by 20ms and, for the slowest 1%, by 150ms. Since NewHope is computationally inexpensive, we're assuming that this is caused entirely by the increased message sizes. Since connection latencies compound on the web (because subresource discovery is delayed), the data requirement of NewHope is moderately expensive for people on slower connections.
None the less, if the need arose, it would be practical to quickly deploy NewHope in TLS 1.2. (TLS 1.3 makes things a little more complex and we did not test with CECPQ1 with it.)
At this point the experiment is concluded. We do not want to promote CECPQ1 as a de-facto standard and so a future Chrome update will disable CECPQ1 support. It's likely that TLS will want a post-quantum key-agreement in the future but a more multilateral approach is preferable for something intended to be more than an experiment.
Roughtime (19 Sep 2016)
Security protocols often assume an accurate, local clock (e.g. TLS, Kerberos, DNSSEC and more). It's a widely accepted assumption when designing protocols but, for a lot of people, it just isn't true. We find good evidence that at least 25% of all certificate errors in Chrome are due to a bad local clock.
Even when the local clock is being synchronised, it's very likely to be using unauthenticated NTP. So if your threat model includes man-in-the-middle attackers then you still can't trust the local clock.
There have been efforts to augment NTP with authentication, but they still assume a world where each client trusts one or more time servers absolutely. In order to explore a solution that allows time servers to be effectively audited by clients, myself and my colleague Matt Braithwaite (with assistance and advice from Ben Laurie and Michael Shields) have developed Roughtime.
Very briefly: using some tricks we believe that it's viable to deploy servers that sign a client-chosen nonce and timestamp on demand. Once you have several of these servers, clients can generate their nonces by hashing replies from other servers with some entropy. That proves that a nonce was created after the reply was received. Clients maintain a chain of nonces and replies and, if a server misbehaves, can use replies from several other servers to prove and report it.
Currently there's only one Roughtime service running, so the idea of spreading trust around is inchoate. But we would like to gauge whether others are interested in this idea, specifically whether there are any organisations who would be seriously interested in deploying something like this in their clients. (Because I assume that, if you have clients, then you'll also be interested in running a server.)
There's a much longer introduction and many more details on the Roughtime site and we've also setup a mailing list.
memcpy (and friends) with NULL pointers (26 Jun 2016)
The C standard (ISO/IEC 9899:2011) has a sane-seeming definition of memcpy (section 188.8.131.52):
The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1.
Apart from a prohibition on passing overlapping objects, I think every C programmer understands that.
However, the standard also says (section 7.1.4):
If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined.
(Emphasis is mine.)
I'm sure that 7.1.4 seemed quite reasonable in isolation, but how does it interact with the case where memcpy is called with a zero length? If you read 18.104.22.168 then you might well think that, since the function copies zero bytes, it's valid to pass NULL as either of the pointer arguments. I claim that the vast majority of C programmers would agree with that, but 7.24.1(2) clarifies that 7.1.4 really does apply:
Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero […] pointer arguments on such a call shall still have valid values, as described in 7.1.4.
(Nobody would actually write memcpy(NULL, NULL, 0), of course, because it (at best) does nothing. But such a call can easily arise at run-time when an empty object is handled by a more general function.)
Some compilers will use this corner of the standard to assume that pointers passed to memcpy are non-NULL, irrespective of the length argument. GCC has built this in, while Clang can get it from the fact that glibc annotates memcpy with nonnull specifications.
Consider the following function:
#include <stdint.h> #include <string.h> int f(uint8_t *dest, uint8_t *src, size_t len) { memcpy(dest, src, len); return dest == NULL; }
Here's the output of building that with GCC 6.1.1 with -O2:
0000000000000000 <f>: 0: 48 83 ec 08 sub rsp,0x8 4: e8 00 00 00 00 call 9 <f+0x9> # memcpy 9: 31 c0 xor eax,eax b: 48 83 c4 08 add rsp,0x8 f: c3 ret
From that we can see that rax (which holds the return value of a function in the amd64 ABI) is unconditionally set to zero, i.e. the compiler has assumed that dest == NULL is false because it has been passed to memcpy. The compiler's reasoning goes like this: 7.1.4 says that passing a NULL pointer to a standard library function is undefined behaviour, therefore if dest was NULL any behaviour is reasonable. So the code can be optimised with the assumption that it's non-NULL, as that's the only case with defined behaviour.
(You can also play with this snippet in Matt Godbolt's excellent tool.)
Opinions on this vary from "the C standard defines the language thus that optimisation is fine by definition" to "that's crazy: there's a huge amount of code out there that probably assumes the obvious behaviour of memcpy". Personally, I find myself further towards the latter position than the former.
Also, it's not just memcpy: the same optimisations are annotated in glibc for (at least) memccpy, memset, memcmp, memchr, memrchr, memmem, mempcpy, bcopy and bcmp. Section 7.1.4 can be applied to any standard library function.
To try and figure out the impact that this optimisation is having I built a number of open-source programs with GCC 6.1.1, with -fno-builtin (to disable GCC's built-in versions of these functions) and with glibc's string.h including, or not, the nonnull annotations. For example, the snippet of code above produces this diff when tested this way:
0000000000000000 <f>: - 0: 48 83 ec 08 sub rsp,0x8 + 0: 53 push rbx + 1: 48 89 fb mov rbx,rdi 4: e8 00 00 00 00 call 9 <f+0x9> 9: 31 c0 xor eax,eax - b: 48 83 c4 08 add rsp,0x8 - f: c3 ret + b: 48 85 db test rbx,rbx + e: 0f 94 c0 sete al + 11: 5b pop rbx + 12: c3 ret
The added code tests dest to set the return value, as intended.
The first program I tested was BIND 9.9.5 because of this advisory that says: "GCC now includes (by default) an optimization which is intended to eliminate unnecessary null pointer comparisons in compiled code. Unfortunately this optimization removes checks which are necessary in BIND and the demonstrated effect is to cause unpredictable assertion failures during execution of named, resulting in termination of the server process". Although version 9.9.5 should be affected according to the advisory, I found no differences in the compiled output based on nonnull annotations in string.h. Perhaps it's because I'm using a different GCC, perhaps I just got something wrong in my testing, or perhaps these checks were eliminated for different reasons. (For example, a local root exploit in the kernel was enabled by a dereference-based removal of a NULL check.)
Next up, I tried something that I'm more involved with: BoringSSL. Here there are two changes: a reordering of two conditions in OPENSSL_realloc_clean (which has no semantic effect) and extensive changes in BN_mod_exp_mont. I'm sure I would be able to do a better analysis if I were more experienced with disassembling large programs, but I'm just using objdump and diff. Still, I believe that all the changes are the result of a single NULL check being removed and then the resulting offset shift of all the following code. That counts as an optimisation, but it's statically clear that the pointer cannot be NULL even without any assumptions about string.h functions so I struggle to give much credit.
Since BoringSSL showed some changes, I tried OpenSSL 1.0.2h. This also shows the same large changes around BN_mod_exp_mont. There's also a large change in dsa_builtin_paramgen2 (a function that we don't have in BoringSSL) but that appears to be another insignificant NULL-check removed and a consequent change of all the later offsets. Lastly, there are a handful of no-op changes: like swapping the arguments to cmp before jne.
Next I tried openssh-7.2p2, which shows no changes. I wondered whether someone had already done this analysis and corrected any problems in OpenSSH so tried a much older version too: 5.4p1. That does show a small, but non-trivial, change in ssh_rsa_verify. After a bit of thought, I believe that GCC has managed to eliminate a test for a non-NULL pointer at the end of openssh_RSA_verify. Just like the BoringSSL case, it's already possible to deduce that the pointer must be non-NULL without any section 7.1.4 assumptions.
It's clear that one has to write C code that's resilient to the compiler assuming that any pointers passed to standard library functions are non-NULL. There have been too many releases of glibc and GCC with this in to safely assume that it'll ever go away.
However, the benefits of this (i.e. the optimisations that the compiler can perform because of it) are nearly zero. Large programs can be built where it has no effect. When there are changes they are either cases that the compiler should have been able to figure out anyway, or else noise changes with no effect.
As for the costs: there have been several cases where removing NULL checks has resulted in a security vulnerability, although I can't find any cases of this precise corner of the C standard causing it. It also adds a very subtle, exceptional case to several very common functions, burdening programmers. But it thankfully rarely seems to make a difference in real-life code, so hopefully there's not a large pool of bugs in legacy code that have been created by this change.
Still, given the huge amount of legacy C code that exists, this optimisation seems unwise to me. Although I've little hope of it happening, I'd suggest that GCC and glibc remove these assumptions and that the next revision of the C standard change 7.24.1(2) to clarify that when a length is zero, pointers can be NULL.
If anyone wishes to check my results here, I've put the scripts that I used on GitHub. I'm afraid that it takes a bit of manual setup and, given variation in GCC versions across systems, some differences are to be expected but the results should be reproducible.
Cryptographic Agility (16 May 2016)
(These are notes that I wrote up from a talk that I gave at the National Academies Forum on Cyber Resilience. You can tell that it was in Washington, DC because of the "cyber".
I wasn't quite sure how technical to pitch this talk so it's relatively introductory; regular readers probably know all this.
This isn't a transcript of what I said, but I try to hit the main points in my notes.)
Firstly I'd like to separate extensibility from agility. A protocol is extensible if you can add features to it without having to update every implementation at the same time—which is generally impossible. Cryptographic agility depends on having extensibility, at least if you ever want to use something that wasn't designed into a protocol at the beginning.
Protocols should be extensible: the world keeps changing and no design is going to be perfect for all time. But extensibility is much harder in practice than it sounds.
I happen to be particularly familiar with TLS and TLS has two, major extensibility mechanisms. The first is a simple version number. Here's how the specification says that it should work:
Client: I support up to version 1.2.
Server: (calculates the minimum of the version that the client supports and the maximum version that the server supports) Ok, let's use version 1.1.
This is commendably simple: it's not possible to express a range of versions and certainly not a discontinuous range. This is about as simple as an extensibility mechanism could be, and yet lots of implementations get it wrong. It's a common mistake for implementations to return an error when the client offers a version number that they don't understand.
This, of course, means that deploying new versions doesn't work. But it's insidious because the server will work fine until someone tries to deploy a new version. We thought that we had flexibility in the protocol but it turned out that bugs in code had rusted it in place.
At this point it's worth recalling the Law of the Internet: blame attaches to the last thing that changed. If Chrome updates and then something stops working then Chrome gets the blame. It doesn't matter that the server couldn't correctly calculate the minimum of two numbers. No normal person understands or cares about that.
What's to be done about this? Well, we work around issues if they're big and suck up the breakage if they're small. It's taken about 15 years to get to the point where web browsers don't have to work around broken version negotiation in TLS and that's mostly because we only have three active versions of TLS. When we try to add a fourth (TLS 1.3) in the next year, we'll have to add back the workaround, no doubt. In summary, this extensibility mechanism hasn't worked well because it's rarely used and that lets bugs thrive.
TLS has a second, major extension mechanism which is a series of (key, value) pairs where servers should ignore unknown keys. This has worked a little better because, while there are only three or four versions in play, with many years between versions, there are 25 to 30 extensions defined. It's not perfect: bugs in implementations have led them to be dependent on the order of extensions and somebody at least managed to write a server that breaks if the last value is empty.
Sometimes more extensibility points have been added inside of extensions in the expectation that it'll save adding another, top-level extension in the future. This has generally been a mistake: these extension points have added complexity for little reason and, when we try to use them, we often find that bugs have rusted them solid anyway. They've just been a waste.
There's a lesson in all this: have one joint and keep it well oiled.
Protocol designers underestimate how badly people will implement their designs. Writing down how you think it should work and hoping that it'll work, doesn't work. TLS's protocol negotiation is trivial and the specification is clear, yet it still didn't work in practice because it's difficult to oil.
Rather one needs to minimise complexity, concentrate all extensibility in a single place and actively defend it. An active defense can take many forms: fuzzing the extensibility system in test suites and compliance testing is good. You might want to define and implement dummy extensions once a year or such, and retire old ones on a similar schedule. When extensions contain lists of values, define a range of values that clients insert at random. In short, be creative otherwise you'll find that bug rust will quickly settle in.
Agility itself
Cryptographic agility is a huge cost. Implementing and supporting multiple algorithms means more code. More code begets more bugs. More things in general means less academic focus on any one thing, and less testing and code-review per thing. Any increase in the number of options also means more combinations and a higher chance for a bad interaction to arise.
Let's just consider symmetric ciphers for a moment. Because everyone wants them to be as fast as possible, BoringSSL currently contains 27 thousand lines of Perl scripts (taken from OpenSSL, who wrote them all) that generate assembly code just in order to implement AES-GCM. That's a tremendous amount of work and a tremendous scope for bugs.
Focusing again on TLS: over the years, 25 different ciphers and modes have been specified for use in TLS. Thankfully, of those, only nine are actively used. But that doesn't mean that the zombies of the others might not still be lurking around, ready to cause problems.
Where did this mess of diversity come from?
1. Old age / we had no idea what we were doing in the 1990's:
A lot of mistakes were made in the 1990's—we really didn't know what we were doing. Phil Rogaway did, but sadly not enough people listened to him; probably because they were busy fighting the US Government which was trying to ban the whole field of study at the time. Unfortunately that coincided with the early inflation period of the internet and a lot of those mistakes were embedded pretty deeply. We're still living with them today.
2. National pride cipher suites
The next cause of excess agility are the national pride cipher suites. Many countries consider cryptography to be an area of national interest but then mistakenly believe that means that they have to invent their own standards and primitives. South Korea and Japan were especially forthright about this and so managed to get these ciphers assigned code points in TLS but Russia and China and, to some extent, many other countries do the same thing.
Although they receive limited analysis compared to something like AES, they're generally not bad, per se, but they bring nothing new to the table: they add nothing but costs, and the costs are significant. Cryptographic diversity for the point of national pride should be strenuously resisted for that reason. Other countries may complain that the US got their standards widely used but the US got to specify a lot about the internet by being the first mover. (And AES is from Belgium anyway.) However, it is the case that I'm not aware of any of these national standards being used to promote something that's actually a deliberate backdoor; which is, of course, not true of the US.
3. Reasonable cases for diversity:
- Embedded systems want to minimise circuit size: AES_128_CCM and AES_256_CCM.
- We want something faster for when we don't have AES hardware: CHACHA20_POLY1305.
- US Government standard, got hardware support from Intel: AES_128_GCM and AES_256_GCM.
Now we come to the ones that are reasonable to use and the reasons for diversity there. It's all about performance optimisation for different environments really: tiny devices want CCM because it only needs an AES-encrypt circuit. Devices without hardware support for AES-GCM want to use ChaCha20-Poly1305 because it's much more efficient in software. Everything else wants to use AES-GCM.
Agility has allowed us to introduce the ciphers in the final set and that's really important. But it's equally important to kill off the old stuff, and that's very hard. Nearly all the incentives are aligned against it. Recall the Law of the Internet (mentioned above); users hate stuff breaking and always blame you. Even djb will take to Twitter when one drops DSA support.
We have a long conveyor belt of primitives, we put new ones at the front and, every so often, we turn the crank and something drops off the end. In addition to all the obvious problems with killing off old stuff, that also means that there's a lot of inadvisable options that will generally function at any given time and this is leading to new products launching with no idea that they're sitting towards the end of this conveyor belt. These products expect a lifetime of some number of years and are unaware that we hope to discontinue something that they're using much sooner than that. It's no longer the case that we can assume that waiting a year will result in a reduction of the amount of use that a deprecated primitive gets because of new launches.
Google tries to address this where it can by requiring support for the newest options in our certification process for devices that interact with our services. But only a tiny subset of the things that interact with Google go through any of our certifications.
Things are even harder in non-interactive cases. TLS at least gets to negotiate between the client and server but algorithms in S/MIME messages and certificate signatures don't allow that. (One can think of ways to help change that, but the current reality is that they're not negotiated.) That's why dropping SHA-1 support in certificates has been a such a gruesome fight and why PKCS#8 messages still require us to support 40-bit RC2.
So what's the lesson here? I'd say that you need extensibility but, when it comes to cryptographic agility, have one option. Maybe two. Fight to keep it that small.
It's worth highlighting that, for the purposes of time, I've simplified things dramatically. I've considered only symmetric ciphers and modes above but, even within TLS, there's a whole separate conveyor belt for asymmetric algorithms. And I've not mentioned the oncoming storm of quantum computers. Quantum computers are going to be hilarious and I hope to be retired before they get big enough to cause problems!
Post-quantum key agreement (24 Dec 2015)
If large quantum computers can be built (and not of the D-Wave variety) then they'll make quite a mess of public-key cryptography. RSA and systems based on discrete logarithms (i.e. finite-field and elliptic-curve Diffie-Hellman) are all broken. I've written about hash-based signatures (which resist quantum attacks) before and the recent PQCRYPTO recommendations suggest those for signatures and McEliece for public-key encryption. Those are both sound, conservative recommendations but both have some size problems: McEliece public keys can be on the order of a megabyte of data and conservative hash-based signatures are about 40KB.
In some situations that's not a problem, and things like firmware signatures, where the key is embedded in hard-to-change silicon, should consider using hash-based signatures today. But those costs motivate the search for post-quantum schemes that are closer to the small, fast primitives that we have today.
One candidate is called Ring Learning-With-Errors (RLWE) and I'll try to give a taste of how it works in this post. This is strongly based on the A New Hope paper by Alkim, Ducas, Pöppelmann & Schwabe, and, in turn, on papers by Bos, Costello, Naehrig & Stebila and Peikert.
Firstly, the basic stats (because I always hate having to dig around for these values in papers). I've included the numbers for a current, elliptic-curve based Diffie-Hellman scheme (X25519) for comparision:
|A New Hope
|Alice's transmission size
|1,824 bytesa
|32 bytes
|Alice's computation
|129,638 cyclesb
|331,568 cyclesc
|Bob's transmission size
|1,824 bytes
|32 bytes
|Bob's computation
|126,236 cycles
|331,568 cycles
(a This is using a more compact scheme than in the paper. b These are Haswell cycle counts from the paper. c These are values from the SUPERCOP benchmark on titan0.)
Something to keep in mind when looking at the numbers above: sending 1,824 bytes on a 10MBit link takes 5.1 million cycles, assuming that your CPU is running at 3.5GHz.
RLWE key agreement
Our fundamental setting is ℤ12289[X]/(X1024+1). That's the set of polynomial equations where the largest power of x is 1023 and the coefficients are values between zero and 12288 (inclusive). For example, 66 + 4532x + 10000x2 + … + 872x1023.
Addition and multiplication can be defined for polynomials in this set. Addition is done by matching up powers of x and adding the corresponding coefficients. If the result is out of range then it's reduced modulo 12289.
Multiplication is high-school polynomial multiplication where the polynomial on the right is multiplied by every term of the polynomial on the left and the result is the sum of those terms. Coefficients are reduced modulo 12289 to keep them in range, but it's likely that the resulting powers of x will be too large—multiplying two x1023 terms gives a result in terms of x2046.
Polynomials with too large a degree can be reduced modulo x1024+1 until they're in range again. So, if we ended up with a term of a×x2046 then we could subtract a×x1022(x1024+1) to eliminate it. By repeated application of that trick, all the terms with powers of x greater than 1023 can be eliminated and then the result is back in the set.
Now that we can add and multiply within this set of polynomials we need to define a noise polynomial: this is simply a polynomial where each coefficient is sampled from a random distribution. In this case, the distribution will be a centered binomial distribution that ranges from -12 to 12. The probability density looks like this:
An important feature of noise polynomials is that the magnitude of each coefficient is small. That will be critical later on.
A random polynomial is one where each coefficient is sampled from a uniform distribution over the full range of zero to 12288.
To build a Diffie-Hellman protocol from this, Alice generates a random polynomial, a, and two noise polynomials, s and e. Alice calculates b = as+e and sends a and b to Bob. Bob generates his own s′ and e′, uses Alice's a to calculate u = as′+e′, and sends u back to Alice. Now Alice can calculate us = (as′+e′)s = as′s+e′s and Bob can calculate bs′ = (as+e)s′ = ass′+es′. But the keen-eyed will notice that those are different values!
The added noise is necessary for security but it means that the two sides to this protocol calculate different values. But, while the values are different, they're very similar because the magnitude of the noise polynomials is small. So a reconciliation mechanism is needed to find a shared value given two, similar polynomials.
So far I've been following the A New Hope paper and it does include a reconciliation mechanism. But, to be honest, I'm not sure that I understand it, so I'm going to be describing a mechanism by Peikert here:
The reconciliation will treat each coefficient in the similar polynomials separately and will extract a single, shared bit from each. Since we're dealing with polynomials that have 1024 terms, we'll get a 1024-bit shared secret in total but I'm just going to discuss the process of processing a single coefficient to get a single bit.
Consider the coefficient space as a circle: zero and 12289 are the same value modulo 12289 and we put that at the top of the circle. At the bottom of the circle will be 12289/2 = 6144 (rounding down). We know that, for each coefficient, Alice and Bob will have similar values—meaning that the values will be close by on the circle.
One option is to split the circle into left and right halves and say that if the point is in the left half then it's a zero, otherwise it's a one.
But while that will work most of the time, there's obviously a problem when the points are near the top or the bottom. In these cases, a small difference in location can result in a point being in a different half, and thus Alice and Bob will get a different result.
In this case we want to split the circle into top (zero) and bottom (one), so that both points are clearly in the bottom half.
But that just moves the problem around to the left and right edges of the circle. So how about we vary the basis in which we measure the points depending where they are? If the point is near the bottom or the top we'll use the top–bottom (blue) basis and, if not, we'll use the left–right (red) basis.
But there's still a problem! Consider the two points in the diagram just above. One party will think that it's in a red area, measure it left–right and conclude that the shared bit is a zero. The other will think it's in a blue area, measure it top–bottom and conclude that the shared bit is a one.
There isn't a solution to this in which the parties operate independently so, instead, one of the parties chooses the basis in which each coefficient will be measured. This information is a single bit of information (i.e. red or blue) that we have Bob send to Alice along with his value u. With this reconciliation information in hand, both parties can measure their points in the same, optimal basis and calculate the same, shared value.
There's lots in the paper that I've skipped over here. Most importantly (for performance), a variant of the Fourier transform can be used to convert the polynomials into the frequency domain where multiplication is much faster. Some of the values transmitted can be transmitted in the frequency domain too to save conversions overall. Also, random polynomials can be sampled directly in the frequency domain.
The parameters here have also been carefully selected so that the reduction stage of multiplication happens magically, just by point-wise multiplication of a some constants before and after the transform.
The a value that Alice generates could be a global constant, but in order to save worrying about how it was generated, and to eliminate the possibility of all-for-the-price-of-one attacks (like LogJam), it's generated fresh for each instance. Rather than transmit it in full, Alice need only send a seed value for it to Bob.
Contrasts with Diffie-Hellman
The most important change from Diffie-Hellman is that this scheme requires that all values be ephemeral. Both QUIC and TLS 1.3 assume that a Diffie-Hellman public-value can be reused but, in this scheme, that breaks the security of the system. More traditional uses of Diffie-Hellman, e.g. TLS 1.2 and SSH, are fine though.
Another important change is that this scheme takes a full round-trip for Alice. With Diffie-Hellman, both parties can transmit a message at time zero and as soon as the other party has received the message, they can calculate the shared key and start transmitting. But even if the a value is a global constant in this scheme, the reconciliation process means that Bob can't send a message until he's received Alice's message, and Alice can't calculate the shared key until she has received Bob's message. So Alice has a wait a full round-trip.
Often that limitation isn't important because other parts of the protocol already require the round-trip (for example, in TLS). But for some uses it's a critical difference.
Also, since this protocol involves random noise it has a failure probability: it's possible that the reconciliation mechanism produces different answers for each side. Thankfully this probability can be made negligible (i.e. less than one in 264).
I should also note that the RLWE problem is hypothesised to be resistant to quantum attack, but we don't know that. We also don't know that it's resistant to attacks by classical computers! It's possible that someone will develop a classical algorithm tomorrow that breaks the scheme above. Thus it should be used concurrently with a standard Diffie-Hellman (e.g. X25519) and the outputs of each should concatenated as the input keying material for a KDF.
Juniper: recording some Twitter conversations (19 Dec 2015)
Update: Ralf wrote up some notes from his work. These now include an update themselves with information from Willem Pinckaers that suggests that the presumed Dual-EC output is exposed to the world in Juniper devices.
On Thursday, Juniper announced that some of their products were affected by "unauthorized code in ScreenOS that could allow a knowledgeable attacker to gain administrative access to NetScreen® devices and to decrypt VPN connections". That sounds like an attacker managed to subvert Juniper's source code repository and insert a backdoor. Of course, any glimpses that we get of these sorts of attacks are fascinating.
Juniper followed up with a slightly more detailed post that noted that there were two backdoors: one via SSH and one that "may allow a knowledgeable attacker who can monitor VPN traffic to decrypt that traffic". Either of these would be very interesting to a nation-state attacker but that latter—passive decryption of VPN connections—is really in their neighborhood.
So, of course, smarter people than I quickly took to Twitter to pull apart the differences in the fixed firmware versions. Since Twitter conversations are terrible to try and pick apart after the fact, I'm writing down the gist of things here. But I'm just the scribe in this case; other people did the work.
One of the first things that people focused on was a difference to a large, hex value that was visible by just diffing the strings of the two firmwares. That change is interesting not just because it's a large, opaque hex string in a binary, but because of the hex strings that immediately precede it. Specially they were:
- FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF: this is the prime order of the underlying field of P-256, a standard elliptic curve.
- FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC: P-256 is typically written in short-Weierstrass form: y2=x3+ax+b. This is then the a value for P-256.
- 5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B: This is the b value for the P-256 equation.
- 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296: This is the x coordinate for the standard generator of P-256—the starting point for operations on the curve.
- FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551: This is the number of points on P-256.
So all the values just before the changed one are constants for P-256, suggesting that the changed value is cryptographic too. The obvious, missing value would be the y coordinate for the standard generator. One possibility was that the attack put in the wrong y value. This could put the generator on the wrong curve, say a weaker curve that shares most of the same parameters as P-256 but with a different value for b. But the curve that would have resulted, while weaker, wasn't real-time-passive-decryption weak. Also the replacement value in the fixed version wasn't the standard y value either.
Ralf-Philipp Weinmann was looking at the code itself and found:
.@agl__ @ioerror @matthew_d_green @sweis ok, it calls EC_POINT_set_compressed_coordinates_GFp() x arg being changed const converted to a BN— Ralf (RPW) (@esizkur) December 18, 2015
That means that the changed value is an x coordinate and that the code was calculating the y value from it given the curve equation. Thus it would only need the x values and the points would always be on the correct curve. So perhaps it's a public key for something?
@sevenps @agl__ @pbarreto @esizkur @ioerror @sweis I agree. A public key for a signature, or a test key.— Matthew Green (@matthew_d_green) December 18, 2015
Changing a public key could easily be a big backdoor, but recall that the result here is somehow passive decryption of VPN traffic. It's unclear how changing a public key could result in passive decryption.
Back at the keyboard, things are making sense again. This will need some digging, but here's a hint: :"EC PRNG KAT failure".— Ralf (RPW) (@esizkur) December 18, 2015
Oh dear. To explain: "EC PRNG" suggests that the value might be a constant in an elliptic-curve based pseudo-random number generator. That could certainly explain how passive decryption of VPN traffic was possible because it brings up memories of Dual-EC. Dual-EC was an NSA effort to introduce a backdoored pseudo-random number generator (PRNG) that, given knowledge of a secret key, allowed an attacker to observe output from the RNG and then predict its future output. If an attacker can predict the output of the PRNG then they can know the keys that one or both sides of a VPN connection will choose and decrypt it. (For more details, see the research paper.)
Indeed, it quickly came to light that Juniper have a page where they say that the VPN devices in question here "do utilize Dual_EC_DRBG, but do not use the pre-defined points cited by NIST". In short, they used a backdoored RNG but changed the locks. Then this attack might be explained by saying that someone broke in and changed the locks again.
We're not sure that's actually what happened, but it seems like a reasonable hypothesis at this point. If it's correct, this is fairly bananas. Dual-EC is not a reasonable RNG: it's massively larger, slower and more complex than standard RNGs. It's output isn't even very uniform. Huge compromises were made in its design in order to meet its primary objective: to be a NOBUS, passive backdoor. ("NOBUS" is an intelligence community term for "nobody but us", i.e. other parties shouldn't be able to use the backdoor.) Why would it be used in ScreenOS in the first place?
If nothing else, Juniper deserves credit for being forthcoming that there was a backdoor, and not just quietly rolling out a patch.— matt blaze (@mattblaze) December 18, 2015
Again, assuming this hypothesis is correct then, if it wasn't the NSA who did this, we have a case where a US government backdoor effort (Dual-EC) laid the groundwork for someone else to attack US interests. Certainly this attack would be a lot easier given the presence of a backdoor-friendly RNG already in place. And I've not even discussed the SSH backdoor which, as Wired notes, could have been the work of a different group entirely. That backdoor certainly isn't NOBUS—Fox-IT claim to have found the backdoor password in six hours.
BoringSSL (17 Oct 2015)
We recently switched Google's two billion line repository over to BoringSSL, our fork of OpenSSL. This means that BoringSSL is now powering Chromium (on nearly all platforms), Android M and Google's production services. For the first time, the majority of Google's products are sharing a single TLS stack and making changes no longer involves several days of work juggling patch files across multiple repositories.
This is a big positive for Google and I'm going to document some of the changes that we've made in BoringSSL in this post. I am not saying that people should be ditching OpenSSL and switching to BoringSSL. For Linux distributions that doesn't even make sense because we've removed too much for many applications to run unaltered and, without linker trickery, it's not possible to have both OpenSSL and BoringSSL in the same process because their symbols will collide. Even if you're in the position of shipping your own TLS stack with your code, you should still heed the warnings in the README well.
OpenSSL have considerably improved their processes since last April, which is great and important because huge swathes of the Internet will continue to depend on it. BoringSSL started before those changes but, even taking them into consideration, I'm still happy with my decision to fork. (But note that Google employs OpenSSL team members Emilia Käsper, Bodo Möller and Ben Laurie and contributes monetarily via the Core Infrastructure Initiative, so we haven't dropped our support of OpenSSL as a project.)
With that in mind, I'm going to mention some of the cleanups that we've done in BoringSSL from the lowest level, upwards. While most people should continue to use OpenSSL, there are lots of developers outside of Google who work on Chromium and Android and thus this document shouldn't be internal to Google. This post may seem critical of OpenSSL, but remember that many of these changes are possible because we only have to worry about Google's needs—we have an order of magnitude fewer platforms and configurations to support than OpenSSL and we don't keep any ABI compatibility. We also have the superpower of being able to change, where needed, the code that calls BoringSSL, so you can't really compare the two.
The "we", above, is primarily myself and my colleagues David Benjamin and Matt Braithwaite. But BoringSSL is open source and Brian Smith has clocked up 55 patches and we've also had contributions from Opera and CloudFlare. (Brian's number would be higher if I had had more time to review his pending changes in the past couple of weeks).
Generally when people say "forking" they mean that they took a copy of the code and started landing patches independently of the original source. That's not what we did with BoringSSL. Rather than start with a copy, I started with an empty directory and went through OpenSSL function-by-function, reformatting, cleaning up (sometimes discarding) and documenting each one. So BoringSSL headers and sources look like this rather than this. The comments in BoringSSL headers can be extracted by a tool to produce documentation of a sort. (Although it could do with a make-over.)
(Clang's formatting tool and its Vim integration are very helpful! It's been the biggest improvement in my code-editing experience in many years.)
For much of the code, lengths were converted from ints to size_ts and functions that returned one, zero or minus one were converted to just returning one or zero. (Not handling a minus one return value is an easy and dangerous mistake.)
I didn't always get everything right: sometimes I discarded a function that we later found we actually needed or I changed something that, on balance, wasn't worth the changes required in other code. Where possible, code that we've needed to bring back has gone into a separate section called "decrepit" which isn't built in Chromium or Android.
But large amounts of OpenSSL could simply be discarded given our more limited scope. All the following were simply never copied into the main BoringSSL: Blowfish, Camllia, CMS, compression, the ENGINE code, IDEA, JPAKE, Kerberos, MD2, MDC2, OCSP, PKCS#7, RC5, RIPE-MD, SEED, SRP, timestamping and Whirlpool. The OpenSSL that we started from has about 468,000 lines of code but, today, even with the things that we've added (including tests) BoringSSL is just 200,000. Even projects that were using OpenSSL's OPENSSL_NO_x defines to exclude functionality at compile time have seen binaries sizes drop by 300KB when switching to BoringSSL.
Some important bits of OpenSSL are too large to bite off all at once, however. The SSL, ASN.1 and X.509 code were "forked" in the traditional sense: they were copied with minimal changes and improved incrementally. (Or, in the case of ASN.1 and X.509, left alone until they could be replaced completely.)
The lowest-levels
OpenSSL has a confusing number of initialisation functions. Code that uses OpenSSL generally takes a shotgun approach to calling some subset of OpenSSL_add_all_algorithms, SSL_library_init, ERR_load_crypto_strings and the deprecated SSLeay aliases of the same. BoringSSL doesn't need any of them; everything works immediately and the errors don't print out funny just because you forgot to load the error strings. If, like Chromium, you care about avoiding static initialisation (because every disk seek to load pages of code delays displaying the window at startup) then you can build with BORINGSSL_NO_STATIC_INITIALIZER and initialise the library when you need with CRYPTO_library_init. But the vast majority of code just wants to avoid having to think about it. In the future, we would like to move to an automatic lazy-init which would solve even Chromium's needs.
OpenSSL and BoringSSL are often built into shared libraries, but OpenSSL doesn't have any visibility annotations. By default symbols are not hidden and ELF requires that any non-hidden symbols can be interposed. So if you look at libcrypto.so in a Linux distribution you'll see lots of internal functions polluting the dynamic symbol table and calls to those functions from within the library have to indirect via the PLT. BoringSSL builds with hidden visibility by default so calls to internal functions are direct and only functions marked OPENSSL_EXPORT are included in the dynamic symbol table.
Multi-threaded code is common these days but OpenSSL requires that you install callbacks to lock and unlock a conceptual array of locks. This trips up people who now take thread-safety to be a given, and can also mean that contention profiling shows a large, opaque amount of contention in the locking callback with no hint as to the real source. BoringSSL has a native concept of locks so is thread-safe by default. It also has "once" objects, atomic reference counting and thread-local storage, which eliminates much of the need for locking in the first place.
OpenSSL has a fairly unique method of handling errors: it pushes errors onto a per-thread queue as the stack unwinds. This means that OpenSSL errors can generally give you something like a stack trace that you might expect from gdb or a Python exception, which is definitely helpful in some cases. For contrast, NSS (Mozilla's crypto library) uses a more traditional, errno-like system of error codes. Debugging an NSS error involves looking up the numeric error code and then grepping the source code to find all the places where that error code can be set and figuring out which triggered this time.
However, this single error-code system is better for programmatic use. Code that tries to do something with OpenSSL errors (other than dumping them for human debugging) tends to look only at the first (i.e. deepest) error on the queue and tries to match on the reason or even function code. Thus changing the name of even internal functions could break calling code because these names were implicitly exported by the error system. Adding errors could also break code because now a different error could be first in the queue. Lastly, forgetting to clear the error queue after a failed function is very easy to do and thus endemic.
So BoringSSL no longer saves functions in the error queue: they all appear as OPENSSL_internal, which saved about 15KB of binary size alone. As a bonus, we no longer need to run a script every time we add a new function. The file name and line number is still saved but, thankfully, I've never seen code try to match line numbers from the error queue. Trying to match on reason codes is still problematic, but we're living with it for now. We also have no good answer for forgetting to clear the error queue. It's possible that we'll change things in the future to automatically clear the error queue when calling most functions as, now that we're using thread-local storage, that'll no longer cause servers to burst into a flaming ball of lock contention. But we've not done that yet.
Parsing and serialisation
OpenSSL's parsing and serialisation involves a lot of incrementing pointers with single-letter names. BoringSSL drags this firmly into the 1990's with functions that automatically check bounds for parsing and functions that automatically resize buffers for serialisation. This code also handles parsing and serialising ASN.1 in an imperative fashion and we're slowly switching over to these functions because the OpenSSL ASN.1 code is just too complicated for us.
But I should note that OpenSSL's master branch now uses some similar parsing functions for parsing TLS structures at least. I've no idea whether that was inspired by BoringSSL, but it's great to see.
Random number generation
Random number generation in OpenSSL suffers because entropy used to be really difficult. There were entropy files on disk that applications would read and write, timestamps and PIDs would be mixed into entropy pools and applications would try other tricks to gather entropy and mix it into the pool. That has all made OpenSSL complicated.
BoringSSL just uses urandom—it's the right answer. (Although we'll probably do it via getrandom rather than /dev/urandom in the future.) There are no return values that you can forget to check: if anything goes wrong, it crashes the address space.
For the vast majority of code, that's all that you need to know, although there are some concessions to performance in the details:
TLS servers that are pushing lots of AES-CBC need the RNG to be really fast because each record needs a random IV. Because of this, if BoringSSL detects that the machine supports Intel's RDRAND instruction, it'll read a seed from urandom, expand it with ChaCha20 and XOR entropy from RDRAND. The seed is thread-local and refreshed every 1024 calls or 1MB output, whichever happens first.
Authenticated Encryption
Handing people a block cipher and hash function and expecting them to figure out the rest does not work. Authenticated Encryption is much closer to being reasonable and BoringSSL promotes it where possible. One very pleasing BoringSSL tale is that I handed that header file to a non-crypto developer and they produced secure code, first time. That would not have happened had I pointed them at EVP_CIPHER.
There is more to be done here as I've talked about before: we need nonce-misuse-resistant primitives and solutions for large files but what we have now is a significant improvement and the foundations for that future work are now in place.
As I mentioned, the SSL/TLS code wasn't reworked function-by-function like most of BoringSSL. It was copied whole and incrementally improved, predominantly by David Benjamin. I'm really happy with what he's managed to do with it.
At the small scale, most of the parsing and serialisation is now using the safe functions that I covered above. (Changes to convert most of the remaining pointer-juggling code are in my review queue.) TLS extensions are now a bit saner and no longer handled with huge switch statements. Support for SSLv2, DSS, SRP and Kerberos has all been dropped. The header file actually has comments.
Some important, small scale cleanups are less obvious. The large number of "functions" that were actually macros around ctrl functions (that bypassed the type system) are now real functions. In order to get TLS 1.0–1.2 you no longer use the ridiculously named SSLv23_method and then disable SSLv2 and SSLv3 by setting options on the SSL_CTX, rather you use TLS_method and control the versions by setting a minimum and maximum version.
There is lots more that I could mention like that.
At the larger scale, the buffer handling code has been substantially improved and the TLS code now does symmetric crypto using the AEAD interface, which cleanly partitions concerns that previously leaked all over the SSL code. We've also rewritten the version negotiation code so it no longer preprocesses the ClientHello and fiddles with method tables to use the correct version. This avoids some duplicated code and session resumption bugs and OpenSSL has since done a similar rewrite for 1.1.0. To solve a particular problem for Chrome, we've added some support for asynchronous private key operations so that slow smartcards don't block the network thread. Much of the DTLS logic has also been rewritten or pruned.
Perhaps most importantly, the state machine is much reduced. Renegotiation has been dropped except for the case of a TLS client handling renegotiation from a server while the application data flow has stopped, and even that is disabled by default. The DTLS code (a source of many bugs) is much saner in light of this.
OpenSSL has always had decent test coverage of lower-level parts like hash functions and ciphers, but testing of the more complex SSL/TLS code has been lacking. Testing that code is harder because you need to be able to produce sufficiently correct handshakes to get close to its edge cases, but you don't want to litter your real code with dozens of options for producing incorrect outputs in order to hit them. In BoringSSL, we've solved this by using a copy of Go's TLS stack for testing and we've littered it with such options. Our tests also stress asynchronous resume points across a range of handshakes. We wrote partial DTLS support in Go to test DTLS-only edge cases like reassembly, replay and retransmission. Along the way, we even discovered one of OpenSSL's old bug workarounds didn't work, allowing both projects to shed some code.
In C, any malloc call may fail. OpenSSL attempts to handle this, but such code is error-prone and rarely tested. It's best to use a malloc which crashes on failure, but for the benefit of consumers who can't, we have a "malloc test" mode. This runs all tests repeatedly, causing each successive allocation to fail, looking for crashes.
We now have 1,139 TLS tests which gives us 70% coverage of the TLS code—still better than any other TLS library that we've used.
The future
Now that we've done the task of aligning Google around BoringSSL, we'll hopefully be able to turn a little bit more attention to some feature work. Support for the IETF-approved ChaCha20-Poly1305 is coming soon. (Brian Smith has a change waiting for me.) Curve25519 and Ed25519 support are likely too. Next year, we will probably start on TLS 1.3 support.
But more cleanups are probably more important. The big one is the elimination of the ASN.1 and X.509 code in many cases. If you recall, we imported that code whole without cleanups and it hasn't been touched since. We've been incrementally replacing uses of the ASN.1 code with the new CBS and CBB functions but X.509 remains as a substantial user. We're not going to be able to drop that code completely because too much expects the X.509 functions to be available for reading and writing certificates, but we can make it so that the rest of the code doesn't depend on it. Then we can put it in a separate library and drop in a new certificate verification library that some of my Chromium colleagues are writing. Most users of BoringSSL will then, transparently, end up using the new library.
In the SSL code, the SSL object itself is a mess. We need to partition state that's really needed for the whole connection from state that can be thrown away after the handshake from state that can be optionally discarded after the handshake. That will save memory in servers as well as improving the clarity of the code. Since we don't have ABI compatibility, we can also reorder the structs to pack them better.
Lastly, we need to make fuzzing part of our process. Michał Zalewski's AFL has substantially improved the state of fuzzing but, whether we're using AFL or LibFuzzer, it's still a one-off for us. It should be much more like our CI builders. So should running clang-analyzer.
(David Benjamin contributed to this post.)
There's an index of all posts and one, long page with them all too. Email: agl AT imperialviolet DOT org.


text: Is there any possibility to add .txt file to .pdf file in a way that text document will be possible to open directly from .pdf file? But I don't want to add it as attachment, I want it as an element (like .jpg is). If I attach .txt in .docx and then convert .docx to .pdf, this .txt file is saved as a picture and only .txt icon is seen.

subset: commoncrawl


text:
500g/0.01g Phone Shaped Digital Pocket Scale (Silver)
Item No.: Capital - OS-CPA-7193
Ratings: (0 review).
Availability: Out of Stock
Price: $10.14 MSRP:$14.23 (Saved $4.09)
Free Standard Shipping
|3+ units
|5+ units
|10+ units
|20+ units
|Price /Unit
|Contact us
Note: Ships from China warehouse. We ship world-wide. Most customers receive in 2-3 weeks. Order will normally be processed in one to two days.
- Cool and fashionable design.
- Elegant blue back light.
- Unit exchange between g, oz, ozt and dwt.
- Digital scale: 500g/0.01g.
- Pocket size for easy carrying and convenient using.
- Powered by one CR2032 battery (included).
What's in the package:
1 * 500g/0.01g Phone Shaped Digital Pocket Scale
Product Reviews
Be the first to write a review for 500g/0.01g Phone Shaped Digital Pocket Scale (Silver)


text:
'Weird Al' Yankovic Parodies Crosby, Stills & Nash with 'Mission Statement' Song
'Weird Al' released another Youtube music video. This time he parodies Crosby, Stills & Nash's "Suite: Judy Blue Eyes" with his new song 'Mission Statement'. He said, "I wanted to do a song about all the ridiculous double-speak and meaningless buzzwords that I've been hearing in office environments my entire life. I just thought it would be ironic to juxtapose that with the song stylings of CSN, whose music pretty much symbolizes the antithesis of corporate America."
To see original source, go to NY DAILY NEWS
Here's two more that were released over the weekend.
'First World Problems'
'The Sports Song'


text:
Does anyone still make surbahars with the classic huge tumbas? Like the massive instrument Irshad Khan uses? All the information I see about sitars online show the smaller modern style. But that's just what I see on the English internet.
Are surbahars with big tumbas still made?
This is for discussions on the Indian sitar and surbahar, This includes films, books, and recordings
Moderators: povster, s1owpoke, cabernethy, coughcapkittykat
Post Reply
3 posts • Page 1 of 1
Re: Are surbahars with big tumbas still made?
This may be a case where the instrument looks larger because of the size of the player. Ive never met Irshad ji but if i had to guess from the video he is about 5'2".
- Posts: 128
- Joined: Fri Sep 25, 2015 10:59 pm
Re: Are surbahars with big tumbas still made?
The surbahar on the youtube clip looks big because the neck isn't so long. I have a recently made more 'full-size' one I play when I'm in Varanasi, north India & IT has a more usual large toomba.
Post Reply
3 posts • Page 1 of 1
Who is online
Users browsing this forum: Bing [Bot] and 1 guest


text:
As church demographics shift, Catholics urged to address 'sin of racism'
A "seismic shift in demographics" in both society and the U.S. Catholic Church in the coming decades will create a church that is far less white, Fr. Bryan Massingale told a New Orleans audience Friday.
The church will be unprepared to deal with that reality, he continued, unless it addresses "the ongoing struggle for racial equality."
Massingale made the comments in an address to priests, seminarians and other officials of the New Orleans Archdiocese.


text:
964 (1989 - 1994)
From pcarworkshop
|TSBs, Parts Guides
|Torque Specifications
|Assembly Drawings
|Shop Manual
|Height and alignment specifications
|Electrical Diagrams
|VIN Decoder
|Owner Manual
|Reference Pictures
|Option Codes
The Basics
|Car Tour
|Jacking the car
Maintenance - Mechanical
Component Procedures
Oil Leaks
|Valve Covers
|Oil Return Tubes
|Chain Covers
|Rear Main Seal
|Breather Tubes
|Chain Tensioner Cover
Maintenance - Body
Maintenance - Interior
|Power Seat Drive
|Removing the door panel
|Door Panels
|Clock Repair
Upgrades and the slippery slope
Contributing Articles
Contributing your own articles in Pcarworkshop is easy! The first step is to see if this topic has already been added to pcarworkshop. Search for similar articles by entering keyworks for the topic you are interested in using the following input area.
- Submitting an article for addition
If you are not able to add your article to pcarworkshop yourself, you have the option to submit a written article via email. Email mailto:firstname.lastname@example.com with your article and it will be converted to wiki format if its suitable. Please submit either Microsoft Word or raw text files. You may include pictures in the email, or we will have a conversation on how to get the pictures into pcarworkshop.


text:
GENEVA (AFP) - - Swine flu will spread further across the world, experts at the World Health Organisation warned Friday, as the number of confirmed cases surged by more than 1,000 and the US reported two more deaths.
Acting WHO Assistant Director-General Keiji Fukuda told reporters that studies by experts indicated a "significant number of people" had been infected, but remained undetected or unconfirmed by laboratory tests.
"Their work also suggests that the virus is transmissible enough that we will expect to see continued community level outbreaks and regional spread," he told a WHO meeting in Geneva on pandemic preparedness.
The latest WHO data showed 7,520 people in 34 countries were confirmed to have caught the influenza A(H1N1) virus, up 1,000 from Thursday.
According to the figures, most of the deaths had occurred in Mexico, where the Mexican officials said death toll rose by two on Friday to 66 with the epidemic having sickened 2,829 people there.
"We cannot know when we will have it contained," Mexican Health Minister Jose Angel Cordova admitted at his daily press briefing.
But, he said, "I expect in this month or next we can be very close ... and that most of the cases will be sporadic."
US health officials also upped the number of US deaths from three to five, reporting that one person had died in Arizona as well as a young man in Texas. Of the three previous US deaths, two were in Texas and one was in Washington state.
The US Centers for Disease Control and Prevention (CDC) said the number of confirmed and probable cases had reached 4,714, with only four states -- Alaska, Mississippi, West Virginia and Wyoming -- having been spared so far.
On Friday, New York City authorities were forced to close three schools, sending home 4,500 students, after an assistant principal of one of the schools was hospitalised in serious condition.
But US officials are poised to relax a travel advisory for Mexico, some three weeks after warning against non-essential travel to the country, which had been at the epicentre of the outbreak.
"Later today, the CDC will likely be posting a downgrade to the travel warning that regards Mexico," Martin Cetron, CDC head of the global migration and quarantine division.
"The warning, which is at a level four alert, will be downgraded to a travel precaution which will focus on those individuals at high risk for complications from influenza," he said.
WHO Director-General Margaret Chan noted the virus had "quickly demonstrated its capacity to spread easily from one person to another, to spread widely within an affected country and to spread rapidly to additional countries."
"We expect this pattern of international spread to continue," she said.
"This is a time of great uncertainty, and great pressure on governments, ministries of health and WHO," she added.
Fresh updates continued to come in from governments around the world, as Ecuador said it had found its first case.
The 11-year-old victim in the port city of Guayaquil arrived from Miami in the United States only days earlier, reported an official, who requested anonymity.
Meanwhile, experts warned that the fallout of the swine flu epidemic is hitting the travel industry hard, and international tourism risks sliding heavily if the swine flu spread is upgraded to a pandemic.
"The probability of a full blown pandemic is relatively low, but there might be another outbreak in full force of swine flu in the next winter in the northern hemisphere," an economist at Britain's Oxford Economics firm, John Walker, told AFP.
If that happened the number of passengers could drop "up to 60 percent," he warned.
The WHO's Fukuda said the behaviour of the virus would change depending on "whether it is winter period in one part of the world or another."
The virus had "a very different pattern" from normal, seasonal flu, warned Fukuda: half of those who had died had been young and otherwise healthy adults.
"Right now we don't know what the future will bring," he added.


text:
Platform Brief: Overview of Intel® Celeron® processor-based platforms for intelligent systems includes highlights, features, and benefits such as intelligent power technology, enhanced graphics capabilities, and virtualization. (v.001, Jan. 2013)
Intel sales engineers offer advice and support to maximize your design. Whether you are looking for design advice or help finding the right Intel partner, we can help.


text:
• Las Vegas kids Panic! At The Disco have now sold 753,752 copies of their debut record Fever You Can't Sweat Out. The album is down at Number 24 from last week's Number 21 position but the band had an 11 percent increase in sales this week.
More News
• Busta Rhymes' new record The Big Bang debuted at Number One on this week's charts. The album sold 208,773 copies in its first week of sales.
• Despite reports that ticket sales for their current tour are floundering, the Dixie Chicks' latest record Taking the Long Way sold another 130,242 copies this week, keeping it at Number Two on the charts.
• Billy Joel's largely television-promoted new record 12 Gardens Live sold a respectable 44,354 copies in its first week on the charts.


text:
Need an IgE Blood Test in Marshfield, WI? Simply order online 24/7 and get a fast, affordable IgE Blood Test at a lab near you (Find More Locations):
Why would I get an IgE Blood Test?
An IgE Blood Test measures the blood IgE antibody levels to things like foods and environmental allergens. People in Marshfield, WI order the IgE Blood Test for general screening for allergies or ongoing tracking.
How much does an IgE Blood Test cost?
Our IgE Blood Test prices include the doctor's order that you need to get tested in Marshfield, WI, all lab fees and taxes, and a pdf copy of your results. For current prices, please CLICK HERE.
We are pleased to offer an IgE Blood Test in Marshfield, WI.
IgE Blood Test in other cities near Marshfield, WI:Arpin | Auburndale | Babcock | Blenker | Chili | Hewitt | Junction City | Milladore | Nekoosa | Pittsville | Port Edwards | Rudolph | Stratford | Vesper | Wisconsin Rapids


text:
Redefine the limits with the all-new BMW M4 GTS
Pushing the boundaries of automotive engineering, the all-new BMW M4 GTS continues the prestigious legacy of exclusive models developed by BMW. Featuring an abundance of ground-breaking technology, a race-track attitude and a limited production number of just 700 worldwide and 30 available for the UK market, this ferocious road-track hybrid offers a truly exclusive driving experience.
All-new BMW M4 GTS Test Drive All-new BMW M4 GTS Enquiry
As a pure performance driving machine, the M4 GTS boasts an array of razor-sharp racing dynamics and a commitment to lightweight design which not only challenge your expectations, but exceed them. Utilising the same technology as the BMW M4 MotoGP Safety Car, the M4 GTS features an innovative water injection system that provides a significant output and torque boost to the already fiercely powerful M TwinPower Turbo six-cylinder engine – an engine capable of 0-60mph in just 3.7 seconds. To control such devastating power, the chassis, front splitter and rear wing have been designed to offer you manual adjustability, providing a platform for perfect aerodynamic balance and allowing vehicle adaptability to the road or racetrack. Add to this, the M-specific coilover suspension and M double-clutch transmission with Drivelogic, and it is without doubt that the M4 GTS delivers a fast-paced, race-inspired driving experience like no other.
The latest all-new BMW M4 GTS video
Adhering to its rich racing pedigree, the exterior features a number of exclusive components to ensure maximum performance. These include exclusive carbon components with adjustable downforce, assisting the vehicle's perfect weight distribution and aerodynamics. Home also to the 19-inch front and 20-inch rear, Star-spoke style 666M light alloy wheels with Michelin Pilot Sport Cup 2 tyres, the M4 GTS displays both dominance and athleticism.
Inside, the M4 GTS carries on its pursuit for automotive perfection with the weight-optimised centre console exquisitely finished in swathes of Alcantara trim with contrast stitching. Destined for use on the racetrack, the M Sport steering wheel includes all the function and control required for any driving scenario such as those produced by the all-powerful M Drive buttons.
All-new BMW M4 GTS exterior photos
All-new BMW M4 GTS interior photos
Highlights of the all-new BMW M4 GTS:
- A limited production number of just 700 worldwide makes the BMW M4 GTS a truly exclusive driving experience
- The innovative water injection system produces a fine spray that allows the M TwinPower Turbo six-cylinder engine to use higher boost pressure and earlier injection timing for a significant output and torque boost
- M double-clutch transmission with Drivelogic has been specially designed for the BMW M high-revving engine, with Launch Control, Low Speed Assistant and an Auto Start-Stop function
- Star-spoke style 666 M style alloy wheels with Michelin Pilot Sport Cup 2 tyres
- Rear lights with pioneering OLED (organic light-emitting diode) technology give this high-performance special model an utterly unique look when night falls
The all-new BMW M4 GTS arrives soon at Spire.


text:
- Explore community
- Identify
- Help
Added: 5th July 2012
Found on embryo dune in Scheveningen, Netherlands.
Other observations of Sand Couch (Elytrigia juncea)
Elytrigia juncea has larger,
Elytrigia juncea has larger, but fewer spikelets and lives at the front of the beach, before the Marram grass starts. This may be E. athrica or a hybrid, as these are quite common.
I think you are right: it
I think you are right: it looks a lot more like E. atherica than E. juncea. Thankyou for the help!
I'm sorry to anyone I may
I'm sorry to anyone I may have offended with my 'revised identification', I was unsure as to how the website worked with regards to reputations etc... It was not my intention to essentially 'poach' the identification, I am now much better informed and realise that clicking the 'I agree' button was sufficient. Thankyou for everyone's help identifying this species, and again I apologise.


text:
Event Search
If you find yourself in charge of organising this year's annual Christmas party, no doubt you'll want to make sure your Christmas Party is one to remember! Here's my helpful guide to ensure your Christmas party goes with a band!
The best venues get booked up fast and you don't want to be left with the only venue in town as your option. Make sure you get a date in everyone's diary as early as possible then start the all-important task of finding the perfect venue.
No one wants to spend their Christmas party in a cramped office or workshop, find a venue off site that's easy to get to and has the option for taxis at the end of the night. If you do have to stay in-house choose a room away from the usual work area and try to make it festive - a little bit of effort goes a long way!
A theme will really bring your party together, perhaps Christmas past or novelty hats or you could even plan an activity like wine tasting to really get everyone involved.
Whatever you do, remember to include enough food for your guests. Find out what your budget is and find a menu that offers something for everyone! For larger groups a buffet can be ideal as it means people can eat when they are ready. If you are wanting to create a real social atmosphere why not try finger food or bowl food which will allow people to move around the room and be more social with their peers.
Music is all important, and whilst you want a few of the Christmas classics make sure you have some tunes to cater for every taste and get people up and dancing! Perhaps there's a secret DJ in the company or you could even introduce a karaoke machine.
So there you have it follow these tips and you're set for a fantastic company Christmas party in 2016.


text:
Controlling and Lowering Blood Pressure With The MOBIUSHD™ (CALM-FIM_US)
This study is currently recruiting participants. (see Contacts and Locations)
Verified November 2016 by Vascular Dynamics, Inc.
Vascular Dynamics, Inc.
Information provided by (Responsible Party):
Vascular Dynamics, Inc.
ClinicalTrials.gov Identifier:
First received: April 9, 2013
Last updated: November 28, 2016
Last verified: November 2016
- Full Text View
- Tabular View
- No Study Results Posted
- Disclaimer
- How to Read a Study Record
No Study Results Posted on ClinicalTrials.gov for this Study
|Study Status:
|This study is currently recruiting participants.
|Estimated Study Completion Date:
|June 2020
|Estimated Primary Completion Date:
|December 2017 (Final data collection date for primary outcome measure)


text:
Football Weekends magazine goes on sale from the start of each month at hundreds of newsagents across the UK and Ireland.
In the UK it is sold, priced £4.50, at selected WHSmith stores in High Streets, service stations, major railway stations and airports. It is on sale at more than 200 outlets of Martins Newsagents and hundreds more independent retailers.
In Northern Ireland and the Republic of Ireland it is stocked at more than 50 Easons stores.
You can of course purchase your copy online and have it delivered to your door. Sign up to a subscription and save money on the cover price!


text:
Elizabeth Lack
Elizabeth Lack has been a botanist with WEST since 1999. She received a B.S. degree in Forest Biology from Colorado State University in 1988. Elizabeth has extensive experience in botanical and wetland work, including rare plant surveys, noxious weed surveys, vegetation classification and mapping, and vegetation inventory and description. Her wetland work includes delineations based on identification of wetland plant and soil characteristics, designing and monitoring created wetlands, and wetland function and value assessments. She is also experienced in related hydrological work, such as stream and water body inventories and riparian surveys.
Elizabeth is highly experienced working in the field, often leading teams in remote or semi-remote locations, and has worked in habitat types ranging from wetland and riparian habitats to grasslands, shrubland, desert, and forest habitats. Her work has been focused in the western United States including work in Washington, Oregon, Idaho, Nevada, Utah, Arizona, Montana, Wyoming, Colorado, New Mexico, Nebraska, and Kansas. She is also familiar with the miombo woodlands of central Africa. Elizabeth served as a Peace Corps volunteer, living and working in Zambia on a forestry project while on a 2-year sabbatical from WEST between 2005 and 2007.
In addition to field work, Elizabeth is an accomplished technical writer and editor, having authored numerous technical reports. She has also been involved in a number of National Environmental Policy Act (NEPA) projects. She is familiar with all phases of the NEPA process and has been project manager or task leader on many Environmental Impact Statements and Environmental Assessments.