Cross-compiler Openssl在Mips 32位元的板子上

MH Chen
7 min readJun 22, 2019

--

首先,你得先準備好環境,也就是toolchain的部分,我是用buildroot。

如果你連toolchain都沒搞定,就先去看看這篇文章吧~

使用 buildroot 建立 Mips Cross-Compiler 的環境

  1. 下載source code

去官網選擇一個你喜歡的版本下載,我自己挑了1.1.1的
https://www.openssl.org/source/old/

$ wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1.tar.gz

2. 解壓縮,然後進去裡面

$ tar zxvf openssl-1.1.1.tar.gz
$ cd openssl-1.1.1

3. 設定屬於你自己的配置

--prefix 這個參數後面接的是你編譯完後的輸出路徑
--cross-compile-prefix 這個參數則是你cross-compiler的編譯指令共有的前綴詞(如果你跟我一樣是用buildroot的話,我想我們的前綴詞是一樣的)

$ setarch i386 ./config --prefix=輸出的路徑 --cross-compile-prefix=mipsel-linux- shared no-asm no-async

有些人可能還需要另外設定CC, CXX, AR, RANLIB這類參數的絕對路徑,但因為我之前建立環境的時候都一起設定在bash裡了,所以不用

如果你要設定的話,也可以直接下在指令裡,像這樣

$ setarch i386 ./config --prefix=/home/OOXX/MipsOpenssl CC=mipsel-linux-gcc指令的路徑 CXX=mipsel-linux-g++的路徑 AR=mipsel-linux-gcc-ar指令的路徑 RANLIB=mipsel-linux-gcc-ranlib指令的路徑 shared no-asm no-async

你覺得打這麼多字很麻煩也可以寫個shell script,反正你開心就好

4. 刪掉makefile裡『-m32的部分』

config生成出來的makefile含有-m32這樣的字串,這是我們不能執行的,所以要手動刪除

$ vim Makefile

進入vim 後可以直接輸入 /-m32 尋找檔案裡的-m32字串

整個檔案大概只有兩個地方有,就是圖片裡選取的地方,直接把字串delet掉就好

5. build起來

$ make
$ make install

只要最後跑完沒跳error你就是成功make完了,接著make install,該輸出的檔案就會輸出到你先前--prefix輸出的路徑了

6. 確認該有的都有了

輸出了很多東西,但我們最重要的那些有沒有呢?
先看看 include/openssl 資料夾下有沒有很多.h檔,像這樣的

再看看 lib資料夾下有沒有 libcrypto.a libcrypto.so libcrypto.so.1.1 libssl.a libssl.so libssl.so.1.1 這幾個重要的 library

7. 看看能不能在板子上跑

在這裡我們會使用到 .a檔和 include/openssl 下的那堆 .h

.so 是動態函式庫,他就像C的 printf 函式一樣,電腦在編譯的時候會去到一個預設的資料夾下找這個函示在不在家。但他不會幫你把這個函式一起打包到執行檔裡,他會每次執行的時候都去呼叫這個函式。

所以,很明顯的用 .so檔的 library 有時候編譯編過是因為你的電腦有這個函式,但不代表你的版子有,所以直接把 .so檔放到板子上也是無法執行。
我們通常都要把 .so檔燒進去,這樣程式執行的時候才找得到

不過有鑒於燒進去略麻煩,只是 test 一下而已不要浪費太多生命去等待。我的板子也有 USB可以用,所以要把 .a檔用起來,反正都編了嘛。

.a檔是靜態函式庫,和 .so不同,在編譯的時候,電腦會直接幫你把你有用到的函式打包進執行檔裡,所以執行檔可能會比較大,但直接放上板子就能執行了。

所以我們寫個C的code來呼叫他一下,code如下

RSA_generate_key 可以產生一對的公私鑰(public and private key)
RSA_size(key) 可以知道目前 key 所需佔用的長度(bytes 數)
RSA_public_encrypt() 是用公鑰來編碼
RSA_private_decryp() 是用私鑰來解碼
RSA_free(key) 釋放 key 所佔用的記憶體

編譯這段 code

$ mipsel-linux-gcc rsademo.c libcrypto.a libssl.a -o rsademo -I 你包了一堆.h檔的那個openssl資料夾所在路徑 -pthread -ldl

編譯成功後直接把執行檔放到你的板子上執行

$ ./rsademo

成功就是這樣子的感覺

我編譯好的東西分享在github上~
下載了也不一定可以執行啦!畢竟板子不一定一樣
https://github.com/pipi9baby/opensslamitboard

Reference. 謝謝這兩篇偉大的作者
http://amitmason.blogspot.com/2016/05/linux-mint-openssl-library.html
https://www.itread01.com/content/1548294676.html

我所遭遇到的困難~

  1. 寫好code gcc的過程 出現 error: undefined reference to ‘dlopen’
    解法:加上參數 -ldl
    參考資料:https://stackoverflow.com/questions/956640/linux-c-error-undefined-reference-to-dlopen
  2. 全搞定後第一次執行 出現 Floating point exception
    解法:./config之前加上 setarch i386
    參考資料:https://stackoverflow.com/questions/7835596/how-do-i-compile-openssl-in-32-bit-mode-on-a-64bit-system
  3. make的時候 出現 error: unrecognized command line option ‘-m32’
    或是 error: unrecognized command line option ‘-m64’
    解法:去Makefile裡把出錯的字串刪掉
    參考資料:https://www.itread01.com/content/1548294676.html
  4. make的時候出現 undefined reference to `getcontext’
    解法:./config 時加上參數 no-async
    參考資料:http://dannysun-unknown.blogspot.com/2017/02/openssl-110d-arm.html

有人看到這裡,覺得感動,所以我要分享一個神奇的網站

http://pkg.musl.cc/openssl-1.1.1b/

這裡有openssl各種板子編譯後的版本,我就不信裡面沒有你的板子。既然都有人編好了,編不出來也就有個退路了,裡面也有其它套件的,簡直寶藏。

Sign up to discover human stories that deepen your understanding of the world.

--

--

MH Chen
MH Chen

Written by MH Chen

紀錄一些自己總是會忘記的東西 也希望分享一些經驗方法,可以透過大家的回饋發現自己的錯誤

Responses (1)

Write a response