OpenSSL Big Number BN_CTX 控制

以下筆記包含:
能找到最好的tutorial http://edc.tversu.ru/elib/inf/0088/0596003943_secureprgckbk-chp-7-sect-4.html
和OpenSSL document page
BN_CTX_new http://www.openssl.org/docs/crypto/BN_CTX_new.html
BN_CTX_start http://www.openssl.org/docs/crypto/BN_CTX_start.html

EDIT: 我寫了一篇比較詳細的用法解釋在StackOverflow OpenSSL BN_CTX usage,雖然是英文但是比較清楚,建議參考。

筆記

BIGNUM函式庫源於libcrypto,包含在OpenSSL內。API定義於 openssl/bn.h
在使用BIGNUM物件之前,永遠需要先initialize,就算他是靜態宣告的物件。




有些OpenSSL函式會要求一定要BN_CTX物件,這又是什麼呢?

BN_CTX是一個放置BIGNUM暫時變數的結構。在連續的子程序呼叫時,動態配置BIGNUM物件較為消耗效能,因此使用BN_CTX結構。
使用方式如下

所以暫時變數是什麼時候放到BN_CTX裡的?
在做 bn = BN_CTX_get(ctx) 時,程式會去看BN_POOL裡有沒有足夠的、還沒被使用的BN_POOL_ITEM,如果沒有就會malloc一個,跟前面其他的ITEM串起來成一個linked list。
最後在BN_CTX_end(ctx)時會呼叫BN_POOL_finish( ) 將所有的暫時物件都free掉。
BN_POOL_ITEM最多不能超過BN_CTX_POOL_SIZE個,預設是16。

至於BN_STACK是在控制程式共BN_CTX_start(ctx)了幾次,最多不能超過BN_CTX_START_FRAMES個,預設32。

使用原則

  1. 如果是一次性的function,如sign, verify, encrypt, decrypt等,可以不用傳BN_CTX當參數,裡面再創就可以了。
  2. 如果一次性function處理的BIGNUM使用完後需要被清除,避免被攻擊者用frozen attack讀取memory裡的值,請使用BN_new( )不要用BN_CTX_get( ),因為function 結束前需要BN_clear_free( )將memory內的值設為0,而BN_CTX_end( )無法清除memory內的資料,只是把pointer改掉而已。
  3. 如果是比較基層的function,常常被重複call in a loop,就用BN_CTX_start( )BN_CTX_get( ),最後BN_CTX_end( )
  4. 如果處理一連串的動作都需要BN_CTX,且處理內容無關安全性,是public parameters,可用BN_CTX_get( ),或著最後最外層的function結束時會執行BN_CTX_free( ),也會把剛剛BN_CTX_get( )時malloc出的空間BN_clear_free( )掉。
  5. 一個function要先call BN_CTX_start( ),然後一連串的BN_CTX_get( ),必須在將ctx作為參數呼叫其它function前執行完BN_CTX_get( ) calls,最後function return前call BN_CTX_end( )

Comments