<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [dev][ipsec][dpdk] strongswan/dpdk源碼分析--(七)ipsec算法配置過程

      1 簡述

      storngswan的配置里用一種固定格式的字符串設置了用于協商的預定義算法。在包協商過程中strongswan將字符串轉換為固定的枚舉值封在數據包里用于傳輸。

      協商成功之后,這組被協商選中的枚舉值會通過netlink接口以xfrm定義好的字符串形式,傳遞給內核,內核再將字符串轉換成pfkey定義的枚舉值,最終進行加密設置。

      DPDK的話,也有其統一的一組枚舉值的抽象。在調用不同的cryptodev pmd時,會想這組值轉換為對應的值或操作,如轉變成openssl對應的API調用。

      見下圖:

       

      1.1 名詞解釋

      ICV:ICV有兩種翻譯,兩種解釋:Integrity Check Value, initial chaining vector。

      通常我們把IV理解為: initial chaining vector; 把ICV理解為:Integrity Check Value

       

      2 strongswan

      在strongswan的配置里,算法是可以通過字符串進行配置的,這樣的字符串如下:

      esp_proposals = aes128-sha384-curve25519-esn,aes128-sha384-esn

      逗號分隔的是兩個套裝。橫線分隔的是不同的階段,加密-認證-協商-是否esn

      手冊里有詳細的解釋:man  ipsec.conf

      The notation is encryption-integrity[-dhgroup][-esnmode].

      上面提到的是字符串格式的定義。具體的字符串到數據包中的值的定義,是在RFC中約定的,見文檔:

      https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites

      https://wiki.strongswan.org/projects/strongswan/wiki/IKEv1CipherSuites

       

      3 netlink/xfrm

      為了使用xfrm的統一接口,strongswan的netlink模塊做了一次轉換

      見代碼:kernel_netlink_ipsec.c

       

      4 linux kernel

      kernel的xfrm模塊將netlink plugin傳遞過來的string轉換成pfkey中定義的枚舉。

      xfrm部分的代碼:xfrm_algo.c

      pfkey中的枚舉定義:linux/pfkeyv2.h

       

      5 dpdk

      dpdk中cryptodev同樣也有自己的封裝定義,按類別分為對稱,非對稱等。

      算法的枚舉值定義在這個地方: rte_crypto_sym.h

      5.1 關鍵API:

      int
      rte_cryptodev_sym_session_init(uint8_t dev_id,
                  struct rte_cryptodev_sym_session *sess,
                  struct rte_crypto_sym_xform *xforms,
                  struct rte_mempool *mempool);

      如,開篇那個圖,所有的算法都是通過這個API注冊進dpdk的。

      在這個數據結構里,它是一個串在一起的鏈表,將加密算法和消息認證碼算法串在一起作為參數傳遞。

      struct rte_crypto_sym_xform {
          struct rte_crypto_sym_xform *next;
          /**< next xform in chain */
          enum rte_crypto_sym_xform_type type
          ; /**< xform type */
          RTE_STD_C11
          union {
              struct rte_crypto_auth_xform auth;
              /**< Authentication / hash xform */
              struct rte_crypto_cipher_xform cipher;
              /**< Cipher xform */
              struct rte_crypto_aead_xform aead;
              /**< AEAD xform */
          };
      };

      接下來逐個討論加密,消息認證和aead的結構:

      5.2 加密:

      struct rte_crypto_cipher_xform {
          enum rte_crypto_cipher_operation op;   // 加密還是解密
          enum rte_crypto_cipher_algorithm algo;  // 哪一種加密算法
          struct {
              uint8_t *data;  
              uint16_t length;
          } key;                                 // 秘鑰及其長度
          struct {
              uint16_t offset;                  // 對于塊分組加密這里是初始化向量的起點(rte_crypto_op??),對于CRT分組加密,這里是counter, CCM的時候,第一個字節保留,第二個自己用來寫入nonce
              uint16_t length;                  // CRT的時候等于block length, CCM的時候是nonce的長度,7-13之間。
          } iv;
      };

      5.3 消息認證:

      struct rte_crypto_auth_xform {
          enum rte_crypto_auth_operation op;
          enum rte_crypto_auth_algorithm algo;
          struct {
              uint8_t *data;
              uint16_t length;    // 必須小于或等于 block size
          } key;
          struct {
              uint16_t offset;    // 初始化向量,需要八字節對齊
              uint16_t length;
          } iv;
          uint16_t digest_length;        // hash算法的截斷長度
      };

      5.4 AEAD:

      struct rte_crypto_aead_xform {
          enum rte_crypto_aead_operation op;
          enum rte_crypto_aead_algorithm algo;
          struct {
              uint8_t *data;
              uint16_t length;
          } key;
          struct {
              uint16_t offset;      // CCM的時候,第一個字節保留,第二個字節用來寫入nonce
              uint16_t length;      // CCM的時候,nonce的長度,7-13之間
          } iv;
          uint16_t digest_length;
          uint16_t aad_length;      // 附加驗證長度??
      };

       

      前文的IV offset與一個結構體相關struct rte_crypto_op cop

      這個結構體是作為參數傳遞給下面api的

      static inline int
      rte_crypto_op_attach_sym_session(struct rte_crypto_op *op,
              struct rte_cryptodev_sym_session *sess)

      在不使用rte_ipsec庫的情況下,op中的一些值需要用戶關心。使用rte_ipsec庫的時候,一般不用關心。rte_ipsec將其封裝在內部處理。

       

      6 rte_ipsec

      在rte_ipsec庫中,圍繞這前文提到的加密算法及其參數主要做了以下三方面的動作:

      1. 通過API rte_cryptodev_sym_session_init()將算法和參數下發給底層的pmd設備。

      2. 為每一個需要加解密的報文準備op(rte_crypto_op),然后attach進session里邊。通過這個函數esp_inb_tun_cop_prepare() [librte_ipsec/sa.c]

      3. 為每一個需要加解密的報文準備數據包的esp封裝。通過這個函數esp_inb_tun_pkt_prepare() [librte_ipsec/sa.c]

      所以在整個rte_ipsec庫的使用過程中。只有保證以上3者的數據和設置可以正常配合,便能保證成功使用。

      詳見:[dev][dpdk][crypto] dpdk加解密設備與IPSEC

      (另外:在分析rte_ipsec的源碼過程中,并沒有發現對API rte_crypto_op_attach_sym_session的調用。奇怪。。。)

       

      7 strongswan libipsec

      基于我們對于dpdk庫的分析,此刻已經了解到,一個算法的基本構成單元,是由方法本身及一組參數構成的。參數為:key長度,iv長度,digest長度,鹽等組成的。

      現在回到strongswan,它的代碼里邊除了對rfc中各個函數的定義以為,一定還擁有這些參數值與辦法定義直接的對應關系。

      前文,我們已經知道與內核通信時的netlink plugin中對這部分參數在傳遞過程中進行了定義,但由于內核的支持有限,所以也并不完整。同時,strongswan也提供了一個用戶態的esp實現,

      叫做libipsec,根據文檔中的描述,該庫對rfc中的所有算法實現了完整的支持。接下來我們對這個庫進行簡要的分析。

       

      進入這部分功能的入口在,函數 create_traditional() [/strongswan.git/src/libipsec/esp_context.c] 中。

      1. create_traditional() 會調用函數crypto_factory.c::create_crypter()

      2. 之后會進入加解密plugin的create函數

      METHOD(crypto_factory_t, create_crypter, crypter_t*,
          private_crypto_factory_t *this, encryption_algorithm_t algo,
          size_t key_size)
      {
          。。。 。。。
          enumerator = this->crypters->create_enumerator(this->crypters);
          while (enumerator->enumerate(enumerator, &entry))
          {
                  。。。 。。。
                  crypter = entry->create_crypter(algo, key_size);
                  。。。 。。。
          }
          。。。 。。。
      }

      紅色字體是一個函數指針,是由下文中的這個宏,注冊進去的。

      METHOD(plugin_t, get_features, int,
          private_aes_plugin_t *this, plugin_feature_t *features[])
      {
          static plugin_feature_t f[] = {
              PLUGIN_REGISTER(CRYPTER, aes_crypter_create),
                              ... ...
          };
              ... ...  
      }

       

      故,逐個分析每一個算法plugin的實現,將能夠得到具體的參數數值。

       

      8 RFC

      一些關于算法參數的細節除了可以查看7中的實現以外,我們還可以查看RFC。

       所有RFC的列表可以從第二章的兩個鏈接關聯出來,便能針對不同的算法找到它所對應的RFC文件了。

      在RFC中有對各種算法的參數特別詳細的描寫。

      https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml

      https://www.iana.org/assignments/ipsec-registry/ipsec-registry.xhtml

      https://www.iana.org/assignments/isakmp-registry/isakmp-registry.xhtml

       

      posted on 2019-03-25 11:47  toong  閱讀(5230)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 黑人异族巨大巨大巨粗| 国产乱对白刺激视频| 国产亚洲综合一区二区三区| 亚洲欧美成人a∨观看| 亚洲精品日本一区二区| 99精品国产综合久久久久五月天| 国产精品国产精品偷麻豆| 97精品伊人久久大香线蕉APP| 国产AV永久无码青青草原| 天天做天天爱夜夜爽导航 | 1区2区3区4区产品不卡码网站| 波多野结衣视频一区二区| 亚洲国产美国产综合一区| 一本一本久久a久久综合精品| 91精品国产色综合久久| 玩弄放荡人妻少妇系列 | 久久综合国产精品一区二区 | 视频一区视频二区视频三区| 国产精品美女黑丝流水| 亚洲日韩国产精品第一页一区 | 99热这里只有成人精品国产| 一级片免费网站| 国产成人av三级在线观看| 中文字幕亚洲精品人妻| 黎城县| 亚洲国产成人无码av在线播放| 亚洲中文一区二区av| 色宅男看片午夜大片啪啪| 露脸国产精品自产拍在线观看| 国产精品线在线精品| 欧美乱妇高清无乱码免费| 小嫩模无套内谢第一次| 亚洲码国产精品高潮在线| 国语精品国内自产视频| 亚洲午夜久久久久久噜噜噜| 无码国内精品久久人妻蜜桃| 亚洲区福利视频免费看| 丝袜老师办公室里做好紧好爽| 亚洲精品综合久久国产二区| 又爽又黄又无遮挡的视频| 精品国产亚洲午夜精品a|