Not only is the Internet dead, it's starting to smell really bad.:2019年08月16日分

2019/08/16(Fri)

[オレオレN6] OpenSSL + ARM

ARMだけNローカルでasmコードにがっつりとローカルパッチ当たってるのだが、一応は元のperlスクリプトに修正して生成したとは思うんだけどそっちの修正がcommitされとらんようなのでめんどくせえ。 というかそのせいでN HEADではOpenSSL-1.1にアプデした時にregenされてローカルの変更がほとんど消し飛んでるんだけどええんかあいつら…

つーかN HEADで消えて問題ない差分ならこっちも捨てても良さそうなんだけど、念のためにNローカルパッチは何をやりたかったのかを出力されたasmコードを元に逆にperlスクリプトを修正しながら推測してみるかね…

つーことでまずはcrypto/aes/asm/aesv8-armx.plの差分

@@ -38,6 +38,7 @@ $prefix="aes_v8";

 $code=<<___;
 #include "arm_arch.h"
+#include "arm_asm.h"

 #if __ARM_MAX_ARCH__>=7
 .text
@@ -930,13 +930,7 @@ if ($flavour =~ /64/) {                    ######## 64-bit code
        if ($arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o) {
            my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
                                         |(($2&7)<<1) |(($2&8)<<2);
-           # since ARMv7 instructions are always encoded little-endian.
-           # correct solution is to use .inst directive, but older
-           # assemblers don't implement it:-(
-           sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
-                       $word&0xff,($word>>8)&0xff,
-                       ($word>>16)&0xff,($word>>24)&0xff,
-                       $mnemonic,$arg;
+           sprintf ".inst\t0x%08x\t@ %s %s",$word,$mnemonic,$arg;
        }
     };

@@ -980,7 +975,7 @@ if ($flavour =~ /64/) {                     ######## 64-bit code
        s/vmov\.32\s+(.*)/unvmov32($1)/geo              or
        s/^(\s+)b\./$1b/o                               or
        s/^(\s+)mov\./$1mov/o                           or
-       s/^(\s+)ret/$1bx\tlr/o;
+       s/^(\s+)ret/$1RET/o;

        print $_,"\n";
     }

まずarm_asm.hってのをN独自に用意してインクルードしてる、これの中身は

#if defined (_ARM_ARCH_4T)
# define RET            bx              lr
#else
# define RET            mov             pc, lr
#endif

とARMv4Tとの差異を吸収するマクロが定義されてて、s/^(\s+)ret/$1bx\tlr/o; → s/^(\s+)ret/$1RET/o; の変更部分と関連している。

そんでスクリプトのコメントに「.inst命令を使うべきだけど古いasには実装されてないので.byte命令使うね」と書かれてる部分があるんだけど、Nはgasだからってことで正しく.instつかうぜという修正をいれておるもよう。

さらにこれ以外にもARM NEON IntrinsicsだかAEONでお買い物だかWAONポイントが溜まるか知らねえけどSIMD命令でなんかやってるとこで結構な差分が出るのは、OpenSSL-1.0.2kにアプデした時にasmコードを再生成しとらんので、 このcommitのCortex-A5x最適化がすっぽり抜け落ちてるんやね、うーんこの。

うーん結局のところ、Nローカルで意図して適用したパッチって実はこのARMv4T対応と.byte→.inst置換くらいで、あとはasmコード再生成忘れによるマージ漏れミスという可能性が高まってきたゾ。 やっぱりリリースエンジニアリング崩壊しとりますな…さすがは限界集落である。

しっかしこのペースでコード監査しとるとマジ終わらんな、ワイみたいにローカルパッチだけでなくOpenSSLそのもののコード監査しとるLibreSSL方面とかガチ苦行としかいいようがない。