AArch64 calling convention

The 64-bit ARM (AArch64) calling convention allocates the 31 general-purpose registers as:[2]

x31 (SP): Stack pointer or a zero register, depending on context.
x30 (LR): Procedure link register, used to return from subroutines.
x29 (FP): Frame pointer.
x19 to x29: Callee-saved.
x18 (PR): Platform register. Used for some operating-system-specific special purpose, or an additional caller-saved register.
x16 (IP0) and x17 (IP1): Intra-Procedure-call scratch registers.
x9 to x15: Local variables, caller saved.
x8 (XR): Indirect return value address.
x0 to x7: Argument values passed to and results returned from a subroutine.

All registers starting with x have a corresponding 32-bit register prefixed with w. Thus, a 32-bit x0 is called w0.

Similarly, the 32 floating-point registers are allocated as:[3]

v0 to v7: Argument values passed to and results returned from a subroutine.
v8 to v15: callee-saved, but only the bottom 64 bits need to be preserved.
v16 to v31: Local variables, caller saved.

From: https://en.wikipedia.org/wiki/Calling_convention#ARM_(A64)

Decrease the tabs bar height in gnome terminal

~/.config/gtk-3.0/gtk.css:

/* Decrease the tabs bar height in gnome-terminal
 * See:
 * https://stackoverflow.com/questions/36869701/decrease-the-tabs-bar-height-in-gnome-terminal
 */
 
terminal-window notebook > header.top button {
  padding: 0 0 0 0;
  background-image: none;
  border: 0;
  margin-right: 10px;
}
 
terminal-window notebook > header.top > tabs > tab {
  margin: 0 0 0 0;
  padding: 0 0 0 0;
}
 
terminal-window notebook > header.top > tabs > tab label {
  padding: 0 0 0 0;
  margin: 0 0 0 0;
}

Before

After

From: https://stackoverflow.com/questions/36869701/decrease-the-tabs-bar-height-in-gnome-terminal

关于AES加解密中CBC模式的IV初始化向量的安全性问题

前段时间,在研究HLS的AES加密,由于一个地方电视台的HLS流有AES加密,在查看了相关的加解密方案后发现使用的是简单的AES的CBC模式,在CBC的模式下,会设置一个IV,初始化向量。但是我在解密的时候,使用了一个由于理解错误而产生的一个错误IV居然也能解密视频并进行播放,于是就有了这篇张文章。

AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

虽然有五种加密,但是常用的还是CBC,CBC的全称Cipher Block Chaining ,有点类似于区块链哈,我们先来看下加密方式

CBC加密

上面的图片从左往右看,初始化IV只有在第一个块加密的时候才会用到,而第N个块的加密IV则是用的N-1(N>1)个加密后的二进制数组。

CBC解密

CBC的解密则也是从左往右看,但是加密时IV在解密时候,只会用于对第一个块进行解密,其他块的解密则是使用上一块的加密二进制作为IV进行解密操作。

加密时,用iv和key去加密第一个块,然后用第一个块的加密数据作为下一个块的iv,依次迭代。解密时,用n-1个块的加密数据作为iv和key去解密第n个块(n>1),只有第一个块才会用加密时的iv去解密第一个块。按照这样的逻辑来看,那么如果解密时,使用了iv错误,出问题的数据应该只有第一个块。

通过上面的分析就能知道,加密的时候,iv会影响所有数据的加密结果,而解密时,iv只会影响第一个加密块的解密结果,其他块的解密可以直接通过分隔加密数据获取正确是N-1块的IV。

这也就印证了为什么ff能播放我用错误的iv解密出来的视频流数据,因为第一块的大小存储大概是id3 的数据,ff直接丢掉id3的数据,直接解码后面的视频数据 ,ff 应该是识别h264编码头开始解码视频。

那么从这点可以看出,在使用了key的情况下,IV对整个数据的保密性没有太大的作用。

再来说说我是怎么发现这个问题,因为错误的IV只会影响第一个块的数据,我在第一次尝试解密后,直接用ff进行播放,ff能够解码并且播放成功,但是相对于其他未加密的HLS流来说,播放我解密后的数据会有3-5s的延时,这让我很是头疼,后来我就通过ffplay -v trace 打印播放解密的日志,发现视频数据的id3信息丢失了,那么出问题出在第一个块。然后再次研究m3u8加解密IV的赋值方法,后发来经过多次试验,正确赋值IV,解密出来的数据能够及时播放。再后来,就出现了这篇文章的来由。

由此带来的延展,针对iv在CBC模式下的弱用,AES提供了更多的模式可供选择,详细的可以到wiki上了解。

https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

From: https://www.jianshu.com/p/45848dd484a9

AS directives: .frame, .mask and .fmask

   high memory   +------------------------+
                 |          ....          |
                 |          ....          |
virtual frame    |       argument n       |
pointer $(fp) ->/+------------------------+\
               / |                        | \
  frame offset   |   local & temporaries  |  \
               \ |                        |   \
                \+------------------------+    \
                 |     saved registers    |      frame size
                 |  (including returnreg) |    /
                 +------------------------+   /
                 |          ....          |  /
   stack         |     argument build     | /
pointer $(sp) -> +------------------------+/
 (framereg)      |          ....          |
                 |          ....          |
                 |                        |
                 |                        |
                 |                        |
    low memory   +------------------------+

.frame framereg, framesize, returnreg
The virtual frame pointer is a frame pointer as used in other compiler systems but has no register allocated for it. It consists of the framereg ($sp, in most cases) added to the framesize. The returnreg specifies the register containing the return address (usually $ra).

.mask bitmask, frameoffset
The .mask directive specifies the registers to be stored and where they are stored. A bit should be on in bitmask for each register saved (for example, if register $31 is saved, bit 31 should be ‘1’ in bitmask. Bits are set in bitmask in little-endian order, even if the machine configuration is big-endian).The frameoffset is the offset from the virtual frame pointer (this number is usually negative).

.fmask bitmask, frameoffset
Notice that saving floating-point registers is identical to saving general registers except we use the .fmask pseudo-op instead of .mask, and the stores are of floating-point singles or doubles.

        .text
        .cfi_sections   .debug_frame
        .align  2
        .globl  main
        .cfi_startproc
        .ent    main
        .type   main, @function
main:
        .frame  $fp,32,$31 # vars= 16, regs= 1/0, args= 0, gp= 0
        .mask   0x40000000,-8
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro
        daddiu  $sp,$sp,-32
        .cfi_def_cfa_offset 32
        sd      $fp,24($sp)
        .cfi_offset 30, -8
        move    $fp,$sp
        .cfi_def_cfa_register 30
        move    $2,$4
        sd      $5,8($fp)
        sll     $2,$2,0
        sw      $2,0($fp)
        .loc 1 6 12
        move    $2,$0
        .loc 1 7 1
        move    $sp,$fp
        .cfi_def_cfa_register 29
        ld      $fp,24($sp)
        daddiu  $sp,$sp,32
        .cfi_restore 30
        .cfi_def_cfa_offset 0
        jr      $31
        nop
        .set    macro
        .set    reorder
        .end    main
        .cfi_endproc
        .size   main, .-main

References
From: http://www.cs.unibo.it/~solmi/teaching/arch_2002-2003/AssemblyLanguageProgDoc.pdf