...

Source file src/github.com/miekg/pkcs11/params.go

Documentation: github.com/miekg/pkcs11

     1  // Copyright 2013 Miek Gieben. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package pkcs11
     6  
     7  /*
     8  #include <stdlib.h>
     9  #include <string.h>
    10  #include "pkcs11go.h"
    11  
    12  static inline void putOAEPParams(CK_RSA_PKCS_OAEP_PARAMS_PTR params, CK_VOID_PTR pSourceData, CK_ULONG ulSourceDataLen)
    13  {
    14  	params->pSourceData = pSourceData;
    15  	params->ulSourceDataLen = ulSourceDataLen;
    16  }
    17  
    18  static inline void putECDH1SharedParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pSharedData, CK_ULONG ulSharedDataLen)
    19  {
    20  	params->pSharedData = pSharedData;
    21  	params->ulSharedDataLen = ulSharedDataLen;
    22  }
    23  
    24  static inline void putECDH1PublicParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pPublicData, CK_ULONG ulPublicDataLen)
    25  {
    26  	params->pPublicData = pPublicData;
    27  	params->ulPublicDataLen = ulPublicDataLen;
    28  }
    29  */
    30  import "C"
    31  import "unsafe"
    32  
    33  // GCMParams represents the parameters for the AES-GCM mechanism.
    34  type GCMParams struct {
    35  	arena
    36  	params  *C.CK_GCM_PARAMS
    37  	iv      []byte
    38  	aad     []byte
    39  	tagSize int
    40  }
    41  
    42  // NewGCMParams returns a pointer to AES-GCM parameters that can be used with the CKM_AES_GCM mechanism.
    43  // The Free() method must be called after the operation is complete.
    44  //
    45  // Note that some HSMs, like CloudHSM, will ignore the IV you pass in and write their
    46  // own. As a result, to support all libraries, memory is not freed
    47  // automatically, so that after the EncryptInit/Encrypt operation the HSM's IV
    48  // can be read back out. It is up to the caller to ensure that Free() is called
    49  // on the GCMParams object at an appropriate time, which is after
    50  //
    51  // Encrypt/Decrypt. As an example:
    52  //
    53  //    gcmParams := pkcs11.NewGCMParams(make([]byte, 12), nil, 128)
    54  //    p.ctx.EncryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_GCM, gcmParams)},
    55  //			aesObjHandle)
    56  //    ct, _ := p.ctx.Encrypt(session, pt)
    57  //    iv := gcmParams.IV()
    58  //    gcmParams.Free()
    59  //
    60  func NewGCMParams(iv, aad []byte, tagSize int) *GCMParams {
    61  	return &GCMParams{
    62  		iv:      iv,
    63  		aad:     aad,
    64  		tagSize: tagSize,
    65  	}
    66  }
    67  
    68  func cGCMParams(p *GCMParams) []byte {
    69  	params := C.CK_GCM_PARAMS{
    70  		ulTagBits: C.CK_ULONG(p.tagSize),
    71  	}
    72  	var arena arena
    73  	if len(p.iv) > 0 {
    74  		iv, ivLen := arena.Allocate(p.iv)
    75  		params.pIv = C.CK_BYTE_PTR(iv)
    76  		params.ulIvLen = ivLen
    77  		params.ulIvBits = ivLen * 8
    78  	}
    79  	if len(p.aad) > 0 {
    80  		aad, aadLen := arena.Allocate(p.aad)
    81  		params.pAAD = C.CK_BYTE_PTR(aad)
    82  		params.ulAADLen = aadLen
    83  	}
    84  	p.Free()
    85  	p.arena = arena
    86  	p.params = &params
    87  	return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params)))
    88  }
    89  
    90  // IV returns a copy of the actual IV used for the operation.
    91  //
    92  // Some HSMs may ignore the user-specified IV and write their own at the end of
    93  // the encryption operation; this method allows you to retrieve it.
    94  func (p *GCMParams) IV() []byte {
    95  	if p == nil || p.params == nil {
    96  		return nil
    97  	}
    98  	newIv := C.GoBytes(unsafe.Pointer(p.params.pIv), C.int(p.params.ulIvLen))
    99  	iv := make([]byte, len(newIv))
   100  	copy(iv, newIv)
   101  	return iv
   102  }
   103  
   104  // Free deallocates the memory reserved for the HSM to write back the actual IV.
   105  //
   106  // This must be called after the entire operation is complete, i.e. after
   107  // Encrypt or EncryptFinal. It is safe to call Free multiple times.
   108  func (p *GCMParams) Free() {
   109  	if p == nil || p.arena == nil {
   110  		return
   111  	}
   112  	p.arena.Free()
   113  	p.params = nil
   114  	p.arena = nil
   115  }
   116  
   117  // NewPSSParams creates a CK_RSA_PKCS_PSS_PARAMS structure and returns it as a byte array for use with the CKM_RSA_PKCS_PSS mechanism.
   118  func NewPSSParams(hashAlg, mgf, saltLength uint) []byte {
   119  	p := C.CK_RSA_PKCS_PSS_PARAMS{
   120  		hashAlg: C.CK_MECHANISM_TYPE(hashAlg),
   121  		mgf:     C.CK_RSA_PKCS_MGF_TYPE(mgf),
   122  		sLen:    C.CK_ULONG(saltLength),
   123  	}
   124  	return C.GoBytes(unsafe.Pointer(&p), C.int(unsafe.Sizeof(p)))
   125  }
   126  
   127  // OAEPParams can be passed to NewMechanism to implement CKM_RSA_PKCS_OAEP.
   128  type OAEPParams struct {
   129  	HashAlg    uint
   130  	MGF        uint
   131  	SourceType uint
   132  	SourceData []byte
   133  }
   134  
   135  // NewOAEPParams creates a CK_RSA_PKCS_OAEP_PARAMS structure suitable for use with the CKM_RSA_PKCS_OAEP mechanism.
   136  func NewOAEPParams(hashAlg, mgf, sourceType uint, sourceData []byte) *OAEPParams {
   137  	return &OAEPParams{
   138  		HashAlg:    hashAlg,
   139  		MGF:        mgf,
   140  		SourceType: sourceType,
   141  		SourceData: sourceData,
   142  	}
   143  }
   144  
   145  func cOAEPParams(p *OAEPParams, arena arena) ([]byte, arena) {
   146  	params := C.CK_RSA_PKCS_OAEP_PARAMS{
   147  		hashAlg: C.CK_MECHANISM_TYPE(p.HashAlg),
   148  		mgf:     C.CK_RSA_PKCS_MGF_TYPE(p.MGF),
   149  		source:  C.CK_RSA_PKCS_OAEP_SOURCE_TYPE(p.SourceType),
   150  	}
   151  	if len(p.SourceData) != 0 {
   152  		buf, len := arena.Allocate(p.SourceData)
   153  		// field is unaligned on windows so this has to call into C
   154  		C.putOAEPParams(&params, buf, len)
   155  	}
   156  	return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
   157  }
   158  
   159  // ECDH1DeriveParams can be passed to NewMechanism to implement CK_ECDH1_DERIVE_PARAMS.
   160  type ECDH1DeriveParams struct {
   161  	KDF           uint
   162  	SharedData    []byte
   163  	PublicKeyData []byte
   164  }
   165  
   166  // NewECDH1DeriveParams creates a CK_ECDH1_DERIVE_PARAMS structure suitable for use with the CKM_ECDH1_DERIVE mechanism.
   167  func NewECDH1DeriveParams(kdf uint, sharedData []byte, publicKeyData []byte) *ECDH1DeriveParams {
   168  	return &ECDH1DeriveParams{
   169  		KDF:           kdf,
   170  		SharedData:    sharedData,
   171  		PublicKeyData: publicKeyData,
   172  	}
   173  }
   174  
   175  func cECDH1DeriveParams(p *ECDH1DeriveParams, arena arena) ([]byte, arena) {
   176  	params := C.CK_ECDH1_DERIVE_PARAMS{
   177  		kdf: C.CK_EC_KDF_TYPE(p.KDF),
   178  	}
   179  
   180  	// SharedData MUST be null if key derivation function (KDF) is CKD_NULL
   181  	if len(p.SharedData) != 0 {
   182  		sharedData, sharedDataLen := arena.Allocate(p.SharedData)
   183  		C.putECDH1SharedParams(&params, sharedData, sharedDataLen)
   184  	}
   185  
   186  	publicKeyData, publicKeyDataLen := arena.Allocate(p.PublicKeyData)
   187  	C.putECDH1PublicParams(&params, publicKeyData, publicKeyDataLen)
   188  
   189  	return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
   190  }
   191  

View as plain text