BigAdmin System Administration Portal
Solaris 10 - Solaris 暗号化フレームワーク
Print-friendly VersionPrint-friendly Version

目次:

  1. はじめに
  2. 暗号化フレームワークのアーキテクチャ
  3. コンポーネントの詳細
  4. 配布
  5. 参考文献
付録 A:ユーザレベルのプログラミング例
 
 
 
 

Solaris 暗号化フレームワークは、コマンド、ユーザーレベルのプログラミングインタフェース、カーネルプログラミングインタフェース、およびユーザーレベルとカーネルレベルのフレームワークを介して、ユーザーとアプリケーションに暗号化サービスを提供します。 これらの暗号化サービスは、エンドユーザーからはシームレスな方法でアプリケーションとカーネルモジュールに提供され、エンドユーザーはファイルの暗号化と復号化といった直接的な暗号化サービスを利用できます。

ユーザーレベルのフレームワークは、コンシューマアプリケーションとエンドユーザーコマンドに暗号化サービスを提供し、カーネルレベルのフレームワークはカーネルモジュールとデバイスドライバに暗号化サービスを提供します。 これらのフレームワークにより、開発者やユーザーはソフトウェアによって最適化された暗号化アルゴリズムを活用できます。

2 つのプログラミングインタフェースは、それぞれのフレームワークのフロントエンドになります。 システム管理者は、暗号化サービスを提供するライブラリやカーネルモジュールを、2 つのフレームワークのどちらかに組み込むことができます。 これで、これらのプラグインの暗号化サービスを、アプリケーションやカーネルモジュールから利用できるようになります。 この柔軟性により、システム管理者は暗号化アルゴリズムのさまざまな実装や、ハードウェアによってアクセラレートされた別々の暗号化プロバイダを組み込むことができます。

 
 

ここでは、Solaris 暗号化フレームワークの大まかなアーキテクチャを説明します。 このアーキテクチャと、その多数のコンポーネントと Solaris オペレーティングシステム (Solaris OS) との関係を次の図に示します。

この図では次の表記規則を使用しています。

  • ソフトウェアコンポーネントは長方形で示しています。
  • 長方形の大きさは、該当する機能の規模や複雑さとは関係がありません。
  • 公開されている (文書化されている) プログラミングインタフェースは、コンポーネントの上部や下部のラベル付きのバーとして示しています。 ソフトウェアモジュールの上部のバーは API を、下部のバーは SPI (サービスプロバイダインタフェース) を表現しています。
  • プラグインは SPI に埋め込まれた長方形で示しています。 これらのプラグインは置き換えたり、フレームワークに追加することができます。 公開されたフレームワークプロバイダインタフェースがある場合、サードパーティはプラグインを記述するだけで済みます。
  • 矢印は大まかな制御フローを示しています (実際の制御フローとは異なる場合がある)。
  • Solaris のプロセス (デーモン) は円で示しています。

2.1 暗号化アプリケーション
 

一般に、アプリケーション層のコンポーネントは、他のアプリケーションに総合的な機能を提供するのではなく、単一クラスの機能だけを実行します。 このようなアプリケーションの例には、Sendmail メールサーバーなどがあります。 Sendmail の役割は、電子メールメッセージの転送を送信先に向けてルーティングすることです。 ホップを辿って次のメールサーバーにメッセージを渡すときに、Sendmail は暗号化を使用してメッセージを保護することができます。 しかし、Sendmail はノード間のそれ以外の通信は保護しません。

Solaris OS の暗号化アーキテクチャでは、アプリケーションそのものには暗号化アルゴリズム (DES など) を組み込みません。 代わりに、Solaris OS から提供される暗号化セキュリティサービスを、これらのアプリケーションから利用します。 この仕組みにより、コードの冗長性が低減され、最適化されたアルゴリズムをどのアプリケーションからも利用できます。

2.2 暗号化セキュリティサービス
 

Solaris OS には、暗号化を間接的に利用する各種のセキュリティサービスがあります。 高レベルのライブラリが、ネットワークを介して通信するエンティティを認証したり、必要に応じてメッセージの完全性とプライバシーを実現するための総合的なインタフェースを提供します。 アプリケーション層のコンポーネントと同様に、これらのセキュリティサービスにも暗号化アルゴリズムは組み込まれていません。 代わりに、これらのセキュリティサービスは、以下の節に記載する共通の暗号化フレームワークセットを利用します。

2.3 フレームワーク
 

フレームワークコンポーネントは、暗号化セキュリティサービスに、暗号化を使用するための統一的な抽象インタフェースを提供します。 これらのインタフェースにより、オペレーティングシステムのコンポーネントの機能に、強力なセキュリティを容易に統合できます。 このようなフレームワークコンポーネントの例には、ユーザーレベルの暗号化フレームワークなどがあります。 このフレームワークは、RSA Security Inc. の PKCS #11 暗号化トークンインタフェース (Cryptoki) 標準 [1] に基づくプログラミングインタフェースをセキュリティサービスに提供します。 さらに、インタフェースはプラグイン式になっているので、適切に署名された暗号化プロバイダは、このフレームワークを介してサービスを登録・提供できます。

暗号化セキュリティサービスコンポーネントと同様に、フレームワークコンポーネントにも暗号化アルゴリズムは直接組み込まれていません。 これらのコンポーネントは、オペレーティングシステムの他のコンポーネントに汎用のプログラミングインタフェースを提供します。

2.4 暗号化プロバイダ
 

実際の暗号化アルゴリズムを提供するのは、最下位層にあるコンポーネントです。 たとえば、この層には、Sun のソフトウェア暗号化プラグインだけを見ても、3DES、 AES、 RSA、 SHA-1 などのソフトウェア実装が含まれています。 これらのプロバイダは、暗号化フレームワークに組み込むことのできる、PKCS #11 に準拠したユーザーレベルのインタフェースと、PKCS #11 ライクなカーネルレベルのインタフェースを提供します。

サードパーティが新しいアルゴリズムを記述したり、Solaris 暗号化フレームワークで使用されている既存のアルゴリズムを置き換えることができるため、このフレームワークでは、それぞれのプロバイダに適切な暗号化署名が埋め込まれているかどうかが検証されます。 この署名により、フレームワークによって認識され、動作が許可されるプロバイダの開発者が制限され、それを使用できるコンシューマが潜在的に制限されます。

 
 

ここでは、Solaris 暗号化フレームワークの主要なコンポーネントを詳しく説明します。

3.1 アプリケーション
 

現在 PKCS#11 を使用して暗号化を利用しているアプリケーションでは、構成を変更するだけでユーザーレベルの暗号化フレームワークをそのまま使用できます。 新しいアプリケーションをライブラリ /usr/lib/libpkcs11.so にリンクすることにより、PKCS#11 の機能を直接利用できます。

ユーザーレベルの暗号化フレームワークの API についての詳細は、第 3.2.1 節を参照してください。

3.1.1 組み込みのエンドユーザーコマンド
 

Solaris 暗号化フレームワークには、ユーザーレベルの暗号化フレームワークを使用するためのエンドユーザーコマンドセットがあり、一般的なユーザーが暗号化サービスを利用できます。

  • digest(1) および mac(1)。
  • ファイルのダイジェストと MAC の計算に使用。 encrypt(1) および decrypt(1)。ファイルの暗号化と復号化に使用。
3.2 フレームワーク
 

ここでは、中核になる Solaris 暗号化フレームワークとその関連コンポーネントを取り上げます。 Solaris 暗号化フレームワークは、プロバイダインタフェースに組み込まれた暗号化プロバイダ群を管理します。 これらのプロバイダの多くは Sun から提供されていますが (第 3.4 節を参照)、サードパーティも暗号化フレームワーク用のプラグインを記述できます。 暗号のセキュリティホールの伝染に対処するため、このフレームワークでは、Sun の暗号化フレームワーク CA から発行された証明書 (公開鍵) に対応する RSA 秘密鍵を使用して、暗号化プロバイダを署名する必要があります。 プロバイダが使用される場合、必ず事前にこの署名が検証されます。

モジュール検証デーモンによるプロバイダの署名の検証を除けば、暗号化フレームワークには暗号化機能は含まれていません。 署名の検証プロセスは次の手順から成り立っています。

  • プロバイダのライブラリ用の署名を抽出する
  • RSA (公開鍵) を使用して署名を復号化する
  • 結果がプロバイダ自身の MD-5 ダイジェストと一致しているかどうかを確認する

この仕組みにより、有効な鍵を取得しなければ、暗号化フレームワークで使用できるプロバイダを開発し、署名することはできません。

暗号化フレームワークは、プロバイダの種類別の 2 つのフレームワークと、これらのフレームワークに登録されたプロバイダの検証を行うユーザーレベルのデーモンから構成されています。

3.2.1 ユーザーレベルの暗号化フレームワーク (uCF)
 

最初のフレームワークはカーネルの外部 (ユーザープロセスレベル) に存在し、ほとんどのコンシューマから利用されます。 このフレームワークをユーザーレベルの暗号化フレームワーク (uCF) と呼びます。 uCF は、暗号化処理を実行する呼び出し元に、PKCS #11 v2.11 に基づく API を提供します。 ユーザーレベルの暗号化フレームワークの API 用として PKCS #11 が選択されたのは、このインタフェースにすでに対応している既存のソフトウェアが大量にあり、このインタフェースについての知識をすでに持っている開発者が大勢いるからです。 uCF のプログラミング例については、付録 A を参照してください。

この API の下位層には、主に多数の暗号化プロバイダを 1 つにまとめ、それらを単一の集約プロバイダに見せかけるロジックがあります。 uCF から (PKCS #11 で言うところの) 「暗号化スロット」が公開されるため、アプリケーションはニーズにもっとも適したプロバイダを選択できます。

uCF の最下位層には、プラグイン式の暗号化プロバイダインタフェースがあります。 暗号化プロバイダを uCF で使用できるようにするには、このインタフェースをプロバイダが実装する必要があります。 このインタフェースは PKCS #11 v2.11 インタフェースに準拠したものでなければならず、さらにプラグインされるプロバイダには暗号化署名が含まれていなければなりません。 この署名は、サンから発行された証明書に含まれている RSA 鍵に対応しています。 このフレームワークでは、モジュール検証デーモンによってプロバイダが正規に使用できるものかどうか、プロバイダに使用制限があるかどうかが検証されます。 このデーモンの詳細については、第 3.3 節を参照してください。

3.2.1.1 便利な関数
 

標準の PKCS #11 インタフェースに加えて、Sun から PKCS #11 の設定とオブジェクトの作成を支援する 2 つの便利な関数が提供されています。 これらの関数は PKCS #11 の他の実装にはなく、uCF の一部として組み込まれています。


CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
          CK_SESSION_HANDLE_PTR hSession);

SUNW_C_GetMechSession() を呼び出すと、フレームワークが初期化され、必要な PKCS #11 コールがすべて実行され、要求したメカニズム上で処理を提供できるセッションが作成されます。 SUNW_C_GetMechSession() を初めて呼び出す前に、C_Initialize() や C_GetSlotList() を呼び出す必要はありません。

この関数の 2 回目以降の呼び出しでは、フレームワークの初期化を行わずに新しいセッションが返されます。 新しいセッションを返せない場合、CKR_SESSION_COUNT が返されます。

不要になったセッションは、C_CloseSession() を使用して解放する必要があります。


CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
        CK_MECHANISM_TYPE mech, const void *rawkey,
         size_t rawkey_len, CK_OBJECT_PTR obj)

SUNW_C_KeyToObject() を呼び出すと、指定したメカニズムの対称鍵オブジェクトが rawkey データから作成されます。 rawkey の値をもとにして、作成される対称鍵オブジェクトの CKA_VALUE 属性が設定されます。 この関数を使用すると、必要な手順をすべて実行しなくても鍵テンプレートを設定できます。 不要になった対称鍵オブジェクトは、C_DestroyObject() を使用して破棄する必要があります。

uCF のAPI の詳細については、RSA PKCS #11 の Web サイト [1] を参照してください。

3.2.2 カーネルレベルの暗号化フレームワーク (kCF)
 

Solaris 暗号化フレームワークのもう 1 つのフレームワークは、カーネル境界の内側に存在しています。 このフレームワークをカーネルレベルの暗号化フレームワーク (kCF) と呼びます。 kCF には uCF と同様の機能があり、Sun やサードパーティから提供される暗号化モジュールやデバイスドライバといった、カーネルモジュールに適したコンシューマインタフェースやプロバイダインタフェースを提供します。 kCF は、Sun やサードパーティの暗号化モジュールやデバイスドライバ用に使用できます。 kCF そのものには暗号化機能はなく、プロバイダの検証機能もありません。 これは、カーネルレベルのプロバイダの検証は、ユーザーレベルで実行されるモジュール検証デーモンに任されるからです。 使用される検証コードは uCF で使われるものと同じです。

kCF と uCF にはいくつかの違いがあります。 kCF には、コンシューマインタフェースとプロバイダインタフェースだけでなく、/dev/crypto と /dev/cryptoadm という 2 つのプライベートデバイスドライバがあります。 /dev/crypto は kCF との通信用に (プロバイダを介して) uCF から使用され、/dev/cryptoadm は kCF との通信用にモジュール検証デーモンと cryptoadm(1M) コマンドから使用されます。 さらに、kCF は暗号化処理用のスケジューリング機能と負荷分散機能をカーネルコンシューマに提供し、非同期モードのコンシューマインタフェースルーチンを提供します。

kCF の API を使用して最適な暗号化アルゴリズムと最適なハードウェアを利用する方法、および kCF の SPI を介して独自の暗号化サービスを提供する方法については、solaris-crypto-api@sun.com に問い合わせてください。

3.3 モジュール検証デーモン
 

モジュール検証デーモンには主に 2 つの役割があります。 その役割とは、kCF に存在し、要求の処理のために使用されるスレッドプールの設定を支援すること、およびユーザーレベルとカーネルレベルのプロバイダの署名の検証要求に応じることです。 署名を検証することにより、すべてのプロバイダが正規のプロバイダ署名鍵によって正しく署名されていることが保証され、プロバイダの使用制限が確認されます。

この仕組みにより、認定を受けなければ、暗号化フレームワークで使用できるプロバイダを記述できません。 この仕組みが必要なのは、米国の輸出規制に適合させるためです。

3.3.1 署名プロバイダ
 

Sun の暗号化フレームワーク CA から発行される証明書の要求フォームを生成するために、elfsign(1) コマンドが提供されています。 証明書を受け取ると、これと同じコマンドを使用して、バイナリの署名と検証を行うことができます。

3.4 暗号化プロバイダ
 

ここでは、Solaris 暗号化フレームワーク用に Sun が開発した、(ユーザーレベルとカーネルレベルの) プロバイダに含まれている暗号化機能を説明します。

3.4.1 Sun ソフトウェア暗号化
 

Solaris OS には、uCF 用と kCF 用に 1 つずつ、合計 2 つのソフトウェア暗号化プロバイダがあります。 これらのプロバイダにより、単一の PKCS #11 インタフェースのもとで多数の暗号化アルゴリズムとダイジェストがまとめられます。 ユーザーレベルの暗号化フレームワークプロバイダ、pkcs11_softtoken.so は次のアルゴリズムに対応しています。

暗号化の代表的な用途アルゴリズム
認証RSA, DSA, Diffie-Hellman, HMAC-MD5, HMAC-SHA-1
ダイジェストMD-5, SHA-1
データプライバシーAES, DES, 3DES, RC4

 

kCF からは、次のアルゴリズムがコンシューマに提供されます。

暗号化の代表的な用途アルゴリズム
認証RSA, HMAC-MD5, HMAC-SHA-1
ダイジェストMD-5, SHA-1
データプライバシーAES, DES, 3DES, Blowfish, RC4

 

ソフトウェアプロバイダの目的は、最適化されたソフトウェア暗号化アルゴリズムの基本セットを提供することにより、これらのアルゴリズムを Solaris のコンポーネントから確実に使用できるようにし、これらのアルゴリズムを再実装しなくても済むようにすることです。 コンシューマはポリシーを定義し、使用できるアルゴリズムを制限できます。プロバイダ全体を取り除くこともできます。

3.4.2 Sun カーネル暗号化プラグイン

uCF には、kCF (pkcs11_kernel.so) との通信だけを目的にしたプロバイダが含まれています。 このプロバイダそのものには暗号化機能はありませんが、uCF から見ると、kCF から提供されるすべての暗号化アルゴリズムが、このプロバイダから提供されているように見えます。 コンシューマが kCF 用のプロバイダを含んだハードウェア暗号化デバイスをインストールした場合、主にこのプロバイダを使用できます。 このプロバイダによって、デバイスの暗号化アルゴリズムを uCF から使用できるようになり、その結果ユーザーレベルのアプリケーションでも、それらを使用できるようになります。

3.5 管理

uCF と kCF の両方を管理するために、cryptoadm(1M) という管理ツールが提供されています。 このツールを使用して、新しいハードウェアプロバイダやソフトウェアプロバイダのインストール、プロバイダのポリシーの定義、暗号化プロバイダについての情報の表示を行うことができます。

3.6 コンシューマ
 

Solaris 10 OS で Solaris 暗号化フレームワークを使用できるように、Solaris の IPsec/IKE と Kerberos (ユーザーレベルとカーネルレベル) が移植されています。 これにより、最適化された暗号化アルゴリズムとハードウェアアクセラレーションを使用できます。

現在 Solaris IPsec では、Solaris IKE の実装の代わりに、サードバーティの鍵管理デーモンを追加できます。 この機能は、従来の鍵管理要件がある場合など、Solaris IKE を使用したくない場合に役立ちます。 Solaris IPsec から鍵管理ソフトウェアに、鍵のインストールやセキュリティの関連付けのための PF_KEY (RFC 2367 [2]) API が提供されます。

 
 

Solaris 暗号化フレームワークは、Solaris 10 オペレーティングシステム (http://www.sun.com/software/solaris/index.jsp) と Solaris Express リリース (http://www.sun.com/software/solaris/solaris-express/) で使用できます。 カーネル暗号化フレームワーク用の API や SPI についての情報は、solaris-crypto-api@sun.com 宛に電子メールを送付することで取得できます。

 
 

この文書で言及している Sun 以外の Web サイトのアクセス性については、Sun は責任を負いません。 これらのサイトや資料に記載されている、またはこれらのサイトや資料を通じて入手できるコンテンツ、広告、製品などについては、Sun は推奨するものではなく、また責任を負いません。 これらのサイトや資料に記載されている、またはこれらのサイトや資料を通じて入手できるコンテンツ、商品、またはサービスによって生じた、またはそれらを使用または信頼することによって生じた実際の損害または主張された損害については、Sun は責任を負いません。

[1] RSA Laboratories, "PKCS #11 - Cryptographic Token Interface Standard," March 2001 (最新バージョンは 2.11)
http://www.rsasecurity.com/rsalabs/pkcs/pkcs-11/index.html
[2] McDonald, D. L., Metz, C., Phan, B. G., "PF_KEY Key Management API, Version 2", July 1998
http://www.ietf.org/rfc/rfc2367.txt

 
 

このサンプルプログラムは、ファイルを読み込み、そのダイジェストを計算します。 このプログラムは、Solaris 暗号化フレームワークに対応したシステムで libpkcs11.so にリンクする必要があります。 このプログラムには移植性はありません。 その理由は、第 3.2.1 節で述べたユーティリティ関数の 1 つを使用しているからです。 このユーティリティ関数を一連の PKCS #11 コールに置き換えると、このプログラムに移植性を持たせることができます。

Copyright 2007 Sun Microsystems, Inc. ALL RIGHTS RESERVED このソフトウェアを使用するには、http://developers.sun.com/berkeley_license.html に記載されているライセンス条項に従う必要があります。


#include ≶stdio.h>
#include ≶fcntl.h>
#include ≶errno.h>
#include ≶sys/types.h>
#include ≶security/cryptoki.h>
#include ≶security/pkcs11.h>

#define BUFFERSIZ 8192
#define MAXDIGEST 64

/*
 * Calculate the digest of a user supplied file.
 */
void
main(int argc, char **argv)
{
      CK_BYTE digest[MAXDIGEST];
      CK_INFO info;
      CK_MECHANISM mechanism;
      CK_SESSION_HANDLE hSession;
      CK_SESSION_INFO Info;
      CK_ULONG ulDatalen = BUFFERSIZ;
      CK_ULONG ulDigestLen = MAXDIGEST;
      CK_RV rv;
      CK_SLOT_ID SlotID;

      int i, bytes_read = 0;
      char inbuf[BUFFERSIZ];
      FILE *fs;
      int error = 0;

      /* Set the digest mechanism to target mechanism */
      mechanism.mechanism = CKM_MD5;
      mechanism.pParameter = NULL_PTR;
      mechanism.ulParameterLen = 0;
      /*
       * Use SUNW convenience function to initialize the cryptoki
       * library, and open a session with a slot that supports
       * the mechanism we plan on using. This same task could be
       * be performed with a series of PKCS #11 calls.
       */
      rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession);
      if (rv != CKR_OK) {
           fprintf(stderr, "SUNW_C_GetMechSession: rv = 0x%.8X\n", rv);
           exit(1);
      }

      /* Get cryptoki information, the manufacturer ID */
      rv = C_GetInfo(&info);
      if (rv != CKR_OK) {
           fprintf(stderr, "WARNING: C_GetInfo: rv = 0x%.8X\n", rv);
      }
      fprintf(stdout, "Manufacturer ID = %s\n", info.manufacturerID);

      /* Open the digest file */
      if ((fs = fopen(argv[1], "r")) == NULL) {
           perror("fopen");
           fprintf(stderr, "\n\tusage: %s filename>\n", argv[0]);
           error = 1;
           goto exit_session;
      }

      /* Initialize the digest session */
      if ((rv = C_DigestInit(hSession, &mechanism)) != CKR_OK) {
           fprintf(stderr, "C_DigestInit: rv = 0x%.8X\n", rv);
           error = 1;
           goto exit_digest;
      }

      /* Read in the data and create digest of this portion */
      while (!feof(fs) && (ulDatalen = fread(inbuf, 1, BUFFERSIZ, fs)) > 0) {
           if ((rv = C_DigestUpdate(hSession, (CK_BYTE_PTR)inbuf,
                          ulDatalen)) != CKR_OK) {
                 fprintf(stderr, "C_DigestUpdate: rv = 0x%.8X\n", rv);
                 error = 1;
                 goto exit_digest;
           }
           bytes_read += ulDatalen;
      }
      fprintf(stdout, "%d bytes read and digested!!!\n\n", bytes_read);

      /* Get complete digest */
      ulDigestLen = sizeof (digest);
      if ((rv = C_DigestFinal(hSession, (CK_BYTE_PTR)digest,
                     &ulDigestLen)) != CKR_OK) {
           fprintf(stderr, "C_DigestFinal: rv = 0x%.8X\n", rv);
           error = 1;
           goto exit_digest;
      }

      /* Print the results */
      fprintf(stdout, "The value of the digest is: ");
      for (i = 0; i ≶ ulDigestLen; i++) {
           fprintf(stdout, "%.2x", digest[i]);
      }
      fprintf(stdout, "\nDone!!!\n");

exit_digest:
      fclose(fs);
exit_session:
      (void) C_CloseSession(hSession);

exit_program:
      (void) C_Finalize(NULL_PTR);

      exit(error);

}
 

この記事は、 The Solaris Cryptographic Framework (By Paul Sangster, Valerie Bubb, Kais Belgaied; March 2005)を翻訳したものです。

BigAdmin
  
 
BigAdmin Upgrade Hub