当前位置: 首页 > 知识库问答 >
问题:

OPENSSL\u ia32\u rdrand cmp/cmove指令

芮意
2023-03-14

我正在尝试理解OpenSSL中使用的x86汇编函数,以使用CPU的RDRAND指令获取随机字节。这是函数体:

OPENSSL_ia32_rdrand:
    mov     $8,%ecx
.Loop_rdrand:
    rdrand  %rax
    jc      .Lbreak_rdrand
    loop    .Loop_rdrand
.Lbreak_rdrand:
    cmp     $0,%rax
    cmove   %rcx,%rax
    ret

我不知道cmp和cmobile指令的用途。我不是x86汇编程序员,但从我看过的参考文献中可以看出,我对它的作用的理解是:

10 load retry counter to ecx
20 get random number into rax
30 if successful (carry flag set) goto 50
40 decrement counter and goto 20 if not zero
50 check if rax is zero
60 if it is, move rcx to rax
70 return 

因此,如果rdrand失败,rax只能为0(进位标志是明确的),并且只有当1)rdrand成功(进位设置)并在rax中放入非零数字,或2)ecx中的重试计数器已减为0时,才能到达cmp指令。在情况1中,cmp失败并且cmobile不执行移动。在情况2中,rcx包含0并且cmobile从0移动到0。无论哪种方式,cmobile都是无操作的。

我是否误解了一个或多个装配说明的作用?

共有2个答案

况景龙
2023-03-14

不仅仅是你有一点误会。无论是谁编写了这个程序,都不知道他们在做什么(嗯,你说的是OpenSSL……真令人惊讶)。英特尔软件开发人员手册建议:

#define SUCCESS 1
#define RETRY_LIMIT_EXCEEDED 0
#define RETRY_LIMIT 10

int get_random_64( unsigned __int 64 * arand)
{
int i ;
for ( i = 0; i < RETRY_LIMIT; i ++)
    {
        if(_rdrand64_step(arand) ) return SUCCESS;
    }
return RETRY_LIMIT_EXCEEDED;
}

在对其进行一些细微的更改以在gcc上编译之后,我得到:

get_random_64:
    movl    $10, %edx
    movl    $1, %ecx

.L3:
    rdrand  %rax
    movq    %rax, (%rdi)
    cmovb   %ecx, %eax
    testl   %eax, %eax
    jne .L4
    subq    $1, %rdx
    jne .L3
    rep ret
.L4:
    movl    $1, %eax
    ret

当随机生成时,这实际上会返回一个零,而不是在这种情况下返回一个小的非零整数。我想说,一个不能返回零且返回1到8之间整数的概率略有增加的随机函数在设计上是有缺陷的,因为它的输出是有偏差的。

颜楚青
2023-03-14

你有点误会。

主要部分答对了,有8次尝试使用RDRAND检索随机数,但如果RDRAND返回0作为随机数,则CMOVE不一定是NOP。在这种情况下,此函数将以“随机数”的形式返回RCX(循环计数)的值。简而言之,此函数仅在没有可用的随机数时返回0,否则它将返回来自随机数的真实随机数,或返回从随机数收到0的迭代数。

 类似资料:
  • 生成RSA秘钥对 以下OpenSSL的genrsagenrsa命令生成一个2048 bit的公钥私 钥对,输出到文件server.key里gist: openssl genrsa -out server.key 2048 server.key是PEM格式pem的: -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DE

  • RSA 公钥私钥 创建公钥私钥 1. 查看 openssl 版本 # openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 2. 创建一个 2048 bit 私钥 # openssl genrsa -out private_key.pem 2048 Generating RSA private key, 2048 bit long modulus ...

  • mongols所包含的所有服务器设施均支持openssl化。也就是说,开发者可以为(tcp|http|resp)协议“一键”开启openssl支持。 开启方法很简单,调用set_openssl方法即可。该方法第一个参数为crt文件,第二个参数是key文件。第三个参数选择openssl协议版本(默认tlsv1.2),第四个参数是ciphers(默认ECDHE-ECDSA-AES128-SHA256:

  • OpenSSL包含一个命令行工具用来完成OpenSSL库中的所有功能,更好的是,它可能已经安装到你的系统中了。 OpenSSL是一个强大的安全套接字层密码库,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,但是,你不应该只将其作为一个库来使用,它还是一个多用途的、跨平台的密码工具。 OpenSSL有许多的特征,而且还有SSL客户端和服务端特征,OpenSSL还有: 美国联邦政府N

  • 我有一个EVP_PKEY结构中的RSA公钥(从PEM文件加载,以------开始公钥------)。现在,我希望能够使用OpenSSL API显示代码中该密钥的指纹。(目的是允许操作员在信任JWT之前使用RS256验证其密钥)。 不幸的是,到目前为止,我发现的所有资源要么在命令行上使用ssh-keygen,要么使用X.509证书的指纹,但不使用公钥。 那么,如何使用OpenSSL API获取存储在

  • 我正在尝试使用带有相同密钥和 iv 的 AES 加密相同的文本。我使用 bash 方法和 ruby 的 openssl stdlib,并对加密结果进行 b64 编码。但结果不同!我试图理解为什么。这是我所做的: 红宝石(1.9.3-p448) 砰砰�� -iv参数设置为上面计算的iv_hex值。 ========================================= 我仔细检查了静脉注