diff options
Diffstat (limited to 'ncr-sessions.c')
-rw-r--r-- | ncr-sessions.c | 199 |
1 files changed, 173 insertions, 26 deletions
diff --git a/ncr-sessions.c b/ncr-sessions.c index c65db2f751e..cb18853d974 100644 --- a/ncr-sessions.c +++ b/ncr-sessions.c @@ -212,6 +212,89 @@ err_sess: return NULL; } +const oid_st* _ncr_properties_to_oid(const struct algo_properties_st * prop, int key_size) +{ +int i = 0; + + if (prop->oids == NULL) + return NULL; + + do { + if (key_size == prop->oids[i].key_size || + prop->oids[i].key_size == -1 /* catch all */) { + + return &prop->oids[i].oid; + } + } while(prop->oids[++i].key_size != 0); + + return NULL; +} + +const static struct algo_oid_st aes_cbc_oids[] = { + {.key_size=16, + .oid = {{2,16,840,1,101,3,4,1,2}, 9}}, + {.key_size=24, + .oid = {{2,16,840,1,101,3,4,1,22}, 9}}, + {.key_size=32, + .oid = {{2,16,840,1,101,3,4,1,42}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st aes_ecb_oids[] = { + {.key_size=16, + .oid = {{2,16,840,1,101,3,4,1,1}, 9}}, + {.key_size=24, + .oid = {{2,16,840,1,101,3,4,1,21}, 9}}, + {.key_size=32, + .oid = {{2,16,840,1,101,3,4,1,41}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st des3_cbc_oids[] = { + {.key_size=-1, + .oid = {{1,2,840,113549,3,7}, 6}}, + {.key_size=0 } +}; + +/* http://www.oid-info.com/get/1.3.6.1.4.1.4929.1.7 + */ +const static struct algo_oid_st des3_ecb_oids[] = { + {.key_size=-1, + .oid = {{1,3,6,1,4,1,4929,1,7}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st camelia_cbc_oids[] = { + {.key_size=16, + .oid = {{1,2,392,200011,61,1,1,1,2}, 9}}, + {.key_size=24, + .oid = {{1,2,392,200011,61,1,1,1,3}, 9}}, + {.key_size=32, + .oid = {{1,2,392,200011,61,1,1,1,4}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st rsa_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,113549,1,1,1}, 7}}, + {.key_size=0 } +}; + +const static struct algo_oid_st dsa_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,10040,4,1}, 6}}, + {.key_size=0 } +}; + +const static struct algo_oid_st dh_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,10046,2,1}, 6}}, + {.key_size=0 } +}; + +/* OIDs are used in cipher algorithms to distinguish keys on key wrapping. + */ + static const struct algo_properties_st algo_properties[] = { #define KSTR(x) .kstr = x, .kstr_len = sizeof(x) - 1 { .algo = NCR_ALG_NULL, KSTR("ecb(cipher_null)"), @@ -219,25 +302,28 @@ static const struct algo_properties_st algo_properties[] = { .key_type = NCR_KEY_TYPE_INVALID }, { .algo = NCR_ALG_3DES_CBC, KSTR("cbc(des3_ede)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("cbc(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = des3_cbc_oids }, + { .algo = NCR_ALG_3DES_ECB, KSTR("ecb(des3_ede)"), + .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, + .key_type = NCR_KEY_TYPE_SECRET, .oids = des3_ecb_oids }, + { .algo = NCR_ALG_AES_CBC, KSTR("cbc(aes)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("cbc(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = aes_cbc_oids }, + { .algo = NCR_ALG_CAMELIA_CBC, KSTR("cbc(camelia)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ctr(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = camelia_cbc_oids }, + { .algo = NCR_ALG_AES_CTR, KSTR("ctr(aes)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ctr(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, + { .algo = NCR_ALG_CAMELIA_CTR, KSTR("ctr(camelia)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ecb(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, + { .algo = NCR_ALG_AES_ECB, KSTR("ecb(aes)"), .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ecb(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = aes_ecb_oids }, + { .algo = NCR_ALG_CAMELIA_ECB, KSTR("ecb(camelia)"), .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, { .algo = NCR_ALG_SHA1, KSTR("sha1"), .digest_size = 20, .can_digest=1, .key_type = NCR_KEY_TYPE_INVALID }, @@ -277,38 +363,77 @@ static const struct algo_properties_st algo_properties[] = { /* NOTE: These algorithm names are not available through the kernel API (yet). */ { .algo = NCR_ALG_RSA, KSTR("rsa"), .is_pk = 1, - .can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, - { .algo = NCR_ALG_RSA, KSTR(NCR_ALG_RSA_TRANSPARENT_HASH), .is_pk = 1, - .can_encrypt=1, .can_sign=1, .has_transparent_hash = 1, - .key_type = NCR_KEY_TYPE_PUBLIC }, + .can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = rsa_oid }, { .algo = NCR_ALG_DSA, KSTR("dsa"), .is_pk = 1, - .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, + .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = dsa_oid }, + { .algo = NCR_ALG_DH, KSTR("dh"), .is_pk = 1, + .can_kx=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = dh_oid }, + { .algo = NCR_ALG_DSA, KSTR(NCR_ALG_DSA_TRANSPARENT_HASH), .is_pk = 1, .can_sign=1, .has_transparent_hash = 1, - .key_type = NCR_KEY_TYPE_PUBLIC }, - { .algo = NCR_ALG_DH, KSTR("dh"), .is_pk = 1, - .can_kx=1, .key_type = NCR_KEY_TYPE_PUBLIC }, + .key_type = NCR_KEY_TYPE_PUBLIC, .oids = rsa_oid }, + { .algo = NCR_ALG_RSA, KSTR(NCR_ALG_RSA_TRANSPARENT_HASH), .is_pk = 1, + .can_encrypt=1, .can_sign=1, .has_transparent_hash = 1, + .key_type = NCR_KEY_TYPE_PUBLIC, .oids = dsa_oid }, + #undef KSTR }; /* The lookups by string are inefficient - can we look up all we need from crypto API? */ -const struct algo_properties_st *_ncr_algo_to_properties(const char *algo) +const struct algo_properties_st *_ncr_algo_to_properties(ncr_algorithm_t algo) { const struct algo_properties_st *a; - size_t name_len; - name_len = strlen(algo); for (a = algo_properties; a < algo_properties + ARRAY_SIZE(algo_properties); a++) { - if (a->kstr_len == name_len - && memcmp(a->kstr, algo, name_len) == 0) + if (a->algo == algo) return a; } return NULL; } +static void print_oid(oid_st* oid) +{ +char txt[128]=""; +char tmp[64]; +int i; + + for (i=0;i<oid->OIDlen;i++) { + sprintf(tmp, "%d.", (int)oid->OID[i]); + strcat(txt, tmp); + } + + dprintk(1, KERN_DEBUG, "unknown oid: %s\n", txt); +} + +const struct algo_properties_st *_ncr_oid_to_properties(oid_st* oid) +{ + const struct algo_properties_st *a; + int i; + + for (a = algo_properties; + a < algo_properties + ARRAY_SIZE(algo_properties); a++) { + + i=0; + + if (a->oids == NULL) continue; + + do { + if (a->oids[i].oid.OIDlen == oid->OIDlen && + memcmp(oid->OID, a->oids[i].oid.OID, oid->OIDlen*sizeof(oid->OID[0]))==0) + return a; + } while(a->oids[++i].key_size != 0); + } + + print_oid(oid); + return NULL; +} + const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla) { const struct algo_properties_st *a; @@ -537,6 +662,14 @@ static struct session_item_st *_ncr_session_init(struct ncr_lists *lists, goto fail; } + /* wrapping keys cannot be used for anything except wrapping. + */ + if (ns->key->flags & NCR_KEY_FLAG_WRAPPING) { + err(); + ret = -EINVAL; + goto fail; + } + if (ns->algorithm->is_hmac && ns->key->type == NCR_KEY_TYPE_SECRET) { if (ns->algorithm->is_pk) { err(); @@ -592,6 +725,14 @@ static struct session_item_st *_ncr_session_init(struct ncr_lists *lists, } if (ns->algorithm->has_transparent_hash) { + /* transparent hash has to be allowed by the key + */ + if (!(ns->key->flags & NCR_KEY_FLAG_ALLOW_TRANSPARENT_HASH)) { + err(); + ret = -EPERM; + goto fail; + } + ns->transparent_hash = kzalloc(ns->hash.digestsize, GFP_KERNEL); if (ns->transparent_hash == NULL) { err(); @@ -1167,6 +1308,12 @@ static int _ncr_session_update_key(struct ncr_lists *lists, ret = -EINVAL; goto fail; } + + if (!(key->flags & NCR_KEY_FLAG_HASHABLE)) { + err(); + ret = -EPERM; + goto fail; + } switch(sess->op) { case NCR_OP_ENCRYPT: |